今天写java验证码程序,完成后使用一切正常,但是总抛出java.lang.IllegalStateException异常,虽然并不影响正常使用,但看了总让人觉得很不舒服,检查代码并没有错,最后上网查了不少资料,终于发现原因之所在。
我们在做文件上传或者下载,或者过滤等操作时,可能要用到页面的输出流.
例如在JSP使用:
response.reset();
response.setContentType(”application/vnd.ms-excel”);
OutputStream os = response.getOutputStream();
抛出异常:
ERROR [Engine] StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
从网上找了下资料,综合一下原因分析:
这是web容器生成的servlet代码中有out.write(””),这个和JSP中调用的response.getOutputStream()产生冲突.
即Servlet规范说明,不能既调用 response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,在调用第二个时候应会抛出 IllegalStateException,因为在jsp中,out变量是通过response.getWriter得到的,在程序中既用了response.getOutputStream,又用了out变量,故出现以上错误。
解决方案:
1.在程序中添加:
out.clear();
out = pageContext.pushBody();
就可以了;
2,不要在%][%之间写内容包括空格和换行符
3,在页面写入图片的时候,需要flush()
OutputStream output=response.getOutputStream();
output.flush();
4,在页面确定写入<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312”>
有人说可能是tomcat的bug,我给她回了封信:
:我看了看这里,http://www.javathinker.org /main.jsp?bc=showessay.jsp+filename=tomcat/tomcat_question_chapter13.htm 这里是你回复别人的一个帖子,里面的观点基本上和我理解的一样,但是你最后写到可能是tomcat的bug,我想解释一下:在jsp中,out是内嵌对象,即已经设置了PrintWriter out=response.getWriter();这样在再次getOutputStream()得到输出流时(比如转发过滤、下载文件时)就出错了 (写排斥锁),我不止一次看到有人的文件下载页面在后台不断打印这个异常。而在servlet中没有默认out内置对象,所以没有出错.你可以在 servlet中添加out对象试试,应该会报异常的.所以正确的处理方式就应该是:在servlet中做控制层,在业务处理以前不要获得out对象,当业务操作失败或出现异常时再生成out对象回显操作结果。
package com.segsec.gisap.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletUtil {
@SuppressWarnings("unchecked")
public static void forward(String url, HttpServletRequest request, HttpServletResponse response) throws IOException{
forward(url, request, response, "utf-8");
}
@SuppressWarnings("unchecked")
public static void forward(String url, HttpServletRequest request, HttpServletResponse response, String encode) throws IOException{
StringBuilder surl = new StringBuilder(url);
Enumeration er = request.getParameterNames();
if(er.hasMoreElements()){
String name = (String) er.nextElement();
surl.append("?").append(name).append("=").append(URLEncoder.encode(request.getParameter(name), encode));
}
while(er.hasMoreElements()){
String name = (String) er.nextElement();
surl.append("&").append(name).append("=").append(URLEncoder.encode(request.getParameter(name), encode));
}
// System.out.println("surl:" + surl);
InputStream is = null;
ServletOutputStream os = null;
try {
os = response.getOutputStream();
URL u = new URL(surl.toString());
is = u.openStream();
byte[] buff = new byte[1024];
int len;
while((len = is.read(buff)) != -1){
os.write(buff, 0, len);
}
os.flush();
} catch (MalformedURLException e) {
e.printStackTrace();
throw new IOException(e);
}finally{
try{
if(is != null){
is.close();
}
}catch (IOException e) {
e.printStackTrace();
}
try{
if(os != null){
os.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.segsec.gisap.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import mapbar.MapbarInterface;
import mapbar.bean.Poi;
import com.general.FormatUtil;
import com.googlecode.jsonplugin.JSONUtil;
import com.segsec.gisap.dao.MenuDAO;
import com.segsec.gisap.util.Config;
/**
* 通过省份名称和查询条件查找地名
* @author Administrator
* 电召的按地址搜索和 地图搜索;
*
*/
public class SearchAddress extends HttpServlet {
private static final long serialVersionUID = 1L;
private boolean searchAddress_use_agent = false;
private String searchAddress_agent_url = "http://113.106.90.236/searchAddress";
@Override
public void init() throws ServletException {
String configPath = Config.getConfigPath();
String systemConfigFile = configPath + "config/system.properties";
try {
Properties properties = com.segsec.gisap.util.Util.loadProperties(systemConfigFile);
searchAddress_use_agent = Boolean.valueOf(properties.getProperty("searchAddress_use_agent"));
searchAddress_agent_url = properties.getProperty("searchAddress_agent_url");
System.out.println("searchAddress_use_agent:" + searchAddress_use_agent);
System.out.println("searchAddress_agent_url:" + searchAddress_agent_url);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if(searchAddress_use_agent){
ServletUtil.forward(searchAddress_agent_url, request, response);
return;
}
/*
* 从客户端取得 城市名称,对应省份子表的名称,查询条件
*/
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/x-json;charset=UTF-8");
PrintWriter pw=response.getWriter();
String tablename = request.getParameter("tablename");
String restrict= FormatUtil.isoconversionutf8(request.getParameter("restrict"));
String iscity=request.getParameter("iscity");
String cityname=request.getParameter("cityname");
int start=Integer.parseInt(request.getParameter("start"));
int end=Integer.parseInt(request.getParameter("limit"));
String str = request.getParameter("isMapbar");
int isMapbar = 0;
if(str != null) {
try {
isMapbar = Integer.parseInt(str);
}catch(Exception e) {}
}
//如果是Mapbar
if(isMapbar == 1) {
int limit = end;
List<Poi> ps = MapbarInterface.getPoiByKeyword(cityname, restrict, 1, limit);
int size = ps.size();
Map map = new HashMap();
map.put("pagenumbercount", size);
Map obj = null;
String tmp = null;
String[] lonlat = null;
List list = new ArrayList();
for(Poi p : ps) {
obj = new HashMap();
obj.put("name", p.getName());
tmp = p.getStrlatlon();
if(tmp != null) {
lonlat = tmp.split(",");
}
if(lonlat != null && lonlat.length > 1) {
obj.put("lon", lonlat[0]);
obj.put("lat", lonlat[1]);
}
obj.put("addname", p.getAddress());
obj.put("telephone", p.getPhone());
list.add(obj);
}
map.put("list", list);
try{
String resp = JSONUtil.serialize(map);
pw.println(resp);
pw.flush();
}catch(Exception ex){
System.out.println("Query SearchAddress to Error"+ex);
}finally{
pw.close();
}
}else {
MenuDAO dao = new MenuDAO();
HashMap hm;
if(iscity!=null&&cityname!=null){
if(cityname.equals("全国")){
hm = dao.queryPOINTALL(tablename, restrict,start,start+end);
}else if(iscity.equals("true")){
hm = dao.queryPOINTCity(tablename, cityname,restrict,start,start+end);
}else{
hm = dao.queryPOINTPro(tablename, restrict,start,start+end);
}
}else{
hm = dao.queryPOINT(tablename, restrict,start,start+end);
}
try{
/*AJAX 对象序列化一个Object 对象输出到客户端*/
String obj=JSONUtil.serialize(hm);
pw.println(obj);
pw.flush();
}catch(Exception ex){
System.out.println("Query SearchAddress to Error"+ex);
}finally{
pw.close();
}
}
}
}
win.findAddressStore
.load({
method : 'post',
params : {
start : 0,
limit : 20,
'tablename' : tablename,
'restrict' : restrict,
cityname : cityname,
isMapbar : 1
// isMapbar || 0
},
callback : function(r,opt,success) {
btn.enable();
if (!success) {
alert("查找失败!:"
+ tablename
+ "\n restrict:"
+ restrict);
}
}
});