JSP页面,用小脚本显示一张图片
<%@page import="java.io.OutputStream"%>
<%@page import="java.io.FileInputStream"%>
<%@page import="java.io.InputStream"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path=request.getRealPath("/");
response.setContentType("image/png");
InputStream is=new FileInputStream(path+"img/2.png");
byte[] content=new byte[is.available()];
is.read(content);
OutputStream os=response.getOutputStream();
os.write(content,0,content.length);
%>
浏览器正常显示了图片,但是控制台报错:
一月 12, 2018 11:45:53 上午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [jsp] in context with path [/jsp2] threw exception [java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:624)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:211)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:118)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:111)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:184)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
at org.apache.jsp.重新定向_jsp._jspService(重新定向_jsp.java:143)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
错误提示:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
getOutputStream 被重复调用的。但是我自己之调用了一次,到底在什么地方被调用了呢?
查找原因:
查找两处,浏览器代码,以及jsp翻译后的java文件
1 /* 2 * Generated by the Jasper component of Apache Tomcat 3 * Version: Apache Tomcat/8.5.24 4 * Generated at: 2018-01-12 04:05:33 UTC 5 * Note: The last modified time of this file was set to 6 * the last modified time of the source file after 7 * generation to assist with modification tracking. 8 */ 9 package org.apache.jsp; 10 11 import javax.servlet.*; 12 import javax.servlet.http.*; 13 import javax.servlet.jsp.*; 14 import java.io.OutputStream; 15 import java.io.FileInputStream; 16 import java.io.InputStream; 17 18 public final class 重新定向_jsp extends org.apache.jasper.runtime.HttpJspBase 19 implements org.apache.jasper.runtime.JspSourceDependent, 20 org.apache.jasper.runtime.JspSourceImports { 21 22 private static final javax.servlet.jsp.JspFactory _jspxFactory = 23 javax.servlet.jsp.JspFactory.getDefaultFactory(); 24 25 private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; 26 27 private static final java.util.Set<java.lang.String> _jspx_imports_packages; 28 29 private static final java.util.Set<java.lang.String> _jspx_imports_classes; 30 31 static { 32 _jspx_imports_packages = new java.util.HashSet<>(); 33 _jspx_imports_packages.add("javax.servlet"); 34 _jspx_imports_packages.add("javax.servlet.http"); 35 _jspx_imports_packages.add("javax.servlet.jsp"); 36 _jspx_imports_classes = new java.util.HashSet<>(); 37 _jspx_imports_classes.add("java.io.OutputStream"); 38 _jspx_imports_classes.add("java.io.FileInputStream"); 39 _jspx_imports_classes.add("java.io.InputStream"); 40 } 41 42 private volatile javax.el.ExpressionFactory _el_expressionfactory; 43 private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; 44 45 public java.util.Map<java.lang.String,java.lang.Long> getDependants() { 46 return _jspx_dependants; 47 } 48 49 public java.util.Set<java.lang.String> getPackageImports() { 50 return _jspx_imports_packages; 51 } 52 53 public java.util.Set<java.lang.String> getClassImports() { 54 return _jspx_imports_classes; 55 } 56 57 public javax.el.ExpressionFactory _jsp_getExpressionFactory() { 58 if (_el_expressionfactory == null) { 59 synchronized (this) { 60 if (_el_expressionfactory == null) { 61 _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 62 } 63 } 64 } 65 return _el_expressionfactory; 66 } 67 68 public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { 69 if (_jsp_instancemanager == null) { 70 synchronized (this) { 71 if (_jsp_instancemanager == null) { 72 _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 73 } 74 } 75 } 76 return _jsp_instancemanager; 77 } 78 79 public void _jspInit() { 80 } 81 82 public void _jspDestroy() { 83 } 84 85 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 86 throws java.io.IOException, javax.servlet.ServletException { 87 88 final java.lang.String _jspx_method = request.getMethod(); 89 if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { 90 response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); 91 return; 92 } 93 94 final javax.servlet.jsp.PageContext pageContext; 95 javax.servlet.http.HttpSession session = null; 96 final javax.servlet.ServletContext application; 97 final javax.servlet.ServletConfig config; 98 javax.servlet.jsp.JspWriter out = null; 99 final java.lang.Object page = this; 100 javax.servlet.jsp.JspWriter _jspx_out = null; 101 javax.servlet.jsp.PageContext _jspx_page_context = null; 102 103 104 try { 105 response.setContentType("text/html; charset=UTF-8"); 106 pageContext = _jspxFactory.getPageContext(this, request, response, 107 null, true, 8192, true); 108 _jspx_page_context = pageContext; 109 application = pageContext.getServletContext(); 110 config = pageContext.getServletConfig(); 111 session = pageContext.getSession(); 112 out = pageContext.getOut(); 113 _jspx_out = out; 114 115 out.write("\r\n");//注意此处out被调用 116 out.write("\r\n"); 117 out.write("\r\n"); 118 out.write("\r\n"); 119 120 String path=request.getRealPath("/"); 121 response.setContentType("image/png"); 122 InputStream is=new FileInputStream(path+"img/2.png"); 123 byte[] content=new byte[is.available()]; 124 is.read(content); 125 OutputStream os=response.getOutputStream(); 126 os.write(content,0,content.length); 127 128 } catch (java.lang.Throwable t) { 129 if (!(t instanceof javax.servlet.jsp.SkipPageException)){ 130 out = _jspx_out; 131 if (out != null && out.getBufferSize() != 0) 132 try { 133 if (response.isCommitted()) { 134 out.flush(); 135 } else { 136 out.clearBuffer(); 137 } 138 } catch (java.io.IOException e) {} 139 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); 140 else throw new ServletException(t); 141 } 142 } finally { 143 _jspxFactory.releasePageContext(_jspx_page_context); 144 } 145 } 146 }
为什么会被调用输入换行呢? 查找 jsp:
标出红线的四个地方有换行,正好4个,和翻译后的java文件中符合。
缩进掉这几个回车,就没有问题了,图片正常显示,控制台没有报错。