当我尝试从响应对象获取ServletOutputStream对象时,我收到了java.lang.IllegalStateException。以下是我的代码:
<%@ page import="java.util.*,java.io.*"%>
<%
try {
System.out.print("request came");
File f = new File ("E:/dd.txt");
String name = f.getName().substring(f.getName().lastIndexOf("/") + 1,f.getName().length());
InputStream in = new FileInputStream(f);
ServletOutputStream outs = response.getOutputStream();
response.setContentType ("application/txt");
response.setHeader ("Content-Disposition", "attachment; filename="+f.getName()+"");
int bit = 256;
int i = 0;
try {
while ((bit) >= 0) {
bit = in.read();
outs.write(bit);
}
} catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
outs.flush();
outs.close();
in.close();
} catch (Exception ioe) {
ioe.printStackTrace(System.out);
}
%>
以下是stacktrace:
java.lang.IllegalStateException
at org.apache.jasper.runtime.ServletResponseWrapperInclude.getOutputStream(ServletResponseWrapperInclude.java:63)
at org.apache.jsp.html.portlet.vitage.custom.QUADWAVE.Procfiledownloadess1_005f36901_005f48.filedownload.downloadscreen_jsp._jspService(downloadscreen_jsp.java:5
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
答案 0 :(得分:5)
您正尝试通过JSP文件中的某些代码下载文件。 JSP作为一种视图技术实际上是工作的错误工具。 <% %>
以外的所有内容(通常是基于文本的内容,如HTML,XML,JSON等)也会写入HTTP响应,包括空格。这只会破坏由Java代码编写的下载内容的完整性,如果您正在提供文档/音频/视频文件等二进制文件,则更是如此。
由于JSP内部使用response.getWriter()
打印所有模板内容(<% %>
之外的所有内容),然后您尝试使用getOutputStream()
,因此导致您的具体问题。这是一个非法的国家。您不能在单个响应中同时使用它们。除了使用getWriter()
之外,您还可以通过删除<% %>
之外的任何空白来解决此问题,包括换行符。
所以,替换
<%@ page import="java.util.*,java.io.*"%>
<%
// Your Java code.
%>
通过
<%@ page import="java.util.*,java.io.*"%><%
// Your Java code.
%>
(并确保在最后%>
之后没有尾随空格/换行符)
但是,您实际上不应该使用JSP来完成这项工作。这就是说这个工作的错误工具。您应该使用正常的HTTP servlet class来完成工作。只需创建一个扩展HttpServlet
的类,并将JSP中的所有Java代码移动到doGet()
方法中。最后将该servlet映射到URL并调用该URL。
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Your Java code.
}
}
您可以在this article中找到更具体的示例。
答案 1 :(得分:0)
您收到错误是因为response.getWriter();
之前已调用response.getOutputStream();
。在服务呼叫中同时呼叫getWriter()
和getOutputStream()
是违法的。而JSP默认使用getWriter()
。
尝试替换
ServletOutputStream outs = response.getOutputStream();
带
PrintWriter outs = response.getWriter();
答案 2 :(得分:0)
您是否尝试使用隐含在jsp上的“out”?
您的程序是否有权从磁盘读取文件?
谢谢,
Prateek
答案 3 :(得分:0)
我建议在servlet中编写文件下载代码。像这样:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext sc = request.getServletContext();
String logFilename = (String) sc.getAttribute("scriptFilename");
String logFilepath = DOWNLOAD_DIR + File.separator + logFilename + LOGFILE_EXTN;
log.debug("file name received: "+logFilename);
log.debug("log file path: "+logFilepath);
File logFile = new File(logFilepath);
OutputStream outStream = null;
FileInputStream inputStream = null;
if(logFile.exists() && logFile.length()!=0) {
log.debug(logFile.getName()+": file exits in the directory.");
String MIME_TYPE = "application/octet-stream";
response.setContentType(MIME_TYPE);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", logFile.getName());
response.setHeader(headerKey, headerValue);
try {
outStream = response.getOutputStream();
inputStream = new FileInputStream(logFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
}catch(IOException io) {
log.debug("exception occured.."+io.getMessage());
} finally {
if(inputStream != null) {
inputStream.close();
}
outStream.flush();
if(outStream != null) {
outStream.close();
}
}
}else {
log.debug(logFile.getName()+" :file not found in the directory.");
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Jmeter Log file not found");
}
}
您可以在jsp中有一个按钮,说“下载”,在onclick处,应调用上述servlet。 这样,您可以在JSP中打印日志。