论坛首页 Java企业应用论坛

out.print引起的post无法获取参数的问题?

浏览 4574 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-06-24  
问题请看下面的红字部分...找到问题的原因了..但是不知道为什么会产生这样的情况,求解答.
1.先有一个工具类如下:
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.http.HttpServletResponse;
/**
 * 将字符串传送到页面
 * @author zcqshine
 *
 */
public class AjaxUtil {
private String jsonResult;
 
/**
 * 将字符串传送到页面
 * @param jsonResult 字符串,json格式的字符串也可以
 */
public AjaxUtil(String jsonResult,HttpServletResponse response){
this.jsonResult = jsonResult;
init(jsonResult, response);
 
public  void init(String jsonResult,HttpServletResponse response) {
if(jsonResult != null && jsonResult.length() > 0){
jsonResult = jsonResult.replaceAll("[\\n\\r]", "");  //去掉换行符
}
 
PrintWriter out;
//response.setContentType("text/plain;charset=utf-8");
response.setCharacterEncoding("gbk");
try {
out = response.getWriter();
out.print(jsonResult);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
 
}
 
public String getJsonResult() {
return jsonResult;
}
 
public void setJsonResult(String jsonResult) {
this.jsonResult = jsonResult;
}
}
 
====================分隔线========================================
2. 再有一个spring注解的方法(controller注解的)
@RequestMapping(value="/callback")
public void callback(HttpServletRequest request,HttpServletResponse response) {
                                new AjaxUtil("SUCCESS",response);//如果这个调用放在此处, 并且外部传参数的方式是POST, 则会导致下面的request.getParameter() 方法获取不到参数以及参数值. 但是GET方式正常
    
String r0_Cmd = formate(request.getParameter("r0_Cmd"));
String p1_MerId = formate(request.getParameter("p1_MerId"));
String p2_Order = formate(request.getParameter("p2_Order"));
String p3_Amt = formate(request.getParameter("p3_Amt"));
String r1_Code = formate(request.getParameter("r1_Code"));
String userid = formate(request.getParameter("userid"));
String gamepid = formate(request.getParameter("gamepid"));
String cpOrderId = formate(request.getParameter("cpOrderId"));
String sign = formate(request.getParameter("sign"));
                                
                               // new AjaxUtil("SUCCESS",response);//如果这个调用放在此处则上面的request.getParameter()不论POST还是GET方法都可以获取到参数以及参数值
 
                                /**
                                    其他方法体省略
                                **/

}

   发表时间:2013-06-24   最后修改:2013-06-25
我测试了下 jetty8 + tomcat6 木有问题,请问你的环境是什么

如果可以请给出demo,方便debug

不好意思。。。 忘了我开着filter了,不过我重新测试了下(servlet3)测试jetty8 没有问题的;

tomcat7是有问题的;和楼下说的原因一样;

在org.apache.catalina.connector.OutputBuffer
Request req = (Request) coyoteResponse.getRequest().getNote(
                CoyoteAdapter.ADAPTER_NOTES);
        req.inputBuffer.close();

一下是Request解析post body 代码
protected byte[] readChunkedPostBody() throws IOException {
        ByteChunk body = new ByteChunk();

        byte[] buffer = new byte[CACHED_POST_LEN];

        int len = 0;
        while (len > -1) {
            len = getStream().read(buffer, 0, CACHED_POST_LEN);
            if (connector.getMaxPostSize() > 0 &&
                    (body.getLength() + len) > connector.getMaxPostSize()) {
                // Too much data
                checkSwallowInput();
                throw new IOException(
                        sm.getString("coyoteRequest.chunkedPostTooLarge"));
            }
            if (len > 0) {
                body.append(buffer, 0, len);
            }
        }
        if (body.getLength() == 0) {
            return null;
        }
        if (body.getLength() < body.getBuffer().length) {
            int length = body.getLength();
            byte[] result = new byte[length];
            System.arraycopy(body.getBuffer(), 0, result, 0, length);
            return result;
        }

        return body.getBuffer();
    }


public InputStream getStream() {
        if (inputStream == null) {
            inputStream = new CoyoteInputStream(inputBuffer);//之前已经关闭了
        }
        return inputStream;
    }

1 请登录后投票
   发表时间:2013-06-24  
去看看 org.apache.catalina.connector 下的源码
response.getWriter().close() 的时候
有一句
req.inputBuffer.close();
1 请登录后投票
   发表时间:2013-06-24   最后修改:2013-06-24
GET方式的请求参数在path中的。在解释http请求头的时候就能得到parameterMap了。
POST方式请求参数放在http消息主体中。在需要的时候(比如第一次getParameter)的时候才会去解释请求实体。

跟楼上说的一样,writer.close()的时候把request的输入给关闭了,导致无法从输入流中获取请求实体,因此无法得到parameterMap

你可以试试在new AjaxUtil("SUCCESS",response); 之前任意调用一下getParameter就正常。
1 请登录后投票
   发表时间:2013-06-25  
jinnianshilongnian 写道
我测试了下 jetty8 + tomcat6 木有问题,请问你的环境是什么

如果可以请给出demo,方便debug

不好意思。。。 忘了我开着filter了,不过我重新测试了下(servlet3)测试jetty8 没有问题的;

tomcat7是有问题的;和楼下说的原因一样;

在org.apache.catalina.connector.OutputBuffer
Request req = (Request) coyoteResponse.getRequest().getNote(
                CoyoteAdapter.ADAPTER_NOTES);
        req.inputBuffer.close();

一下是Request解析post body 代码
protected byte[] readChunkedPostBody() throws IOException {
        ByteChunk body = new ByteChunk();

        byte[] buffer = new byte[CACHED_POST_LEN];

        int len = 0;
        while (len > -1) {
            len = getStream().read(buffer, 0, CACHED_POST_LEN);
            if (connector.getMaxPostSize() > 0 &&
                    (body.getLength() + len) > connector.getMaxPostSize()) {
                // Too much data
                checkSwallowInput();
                throw new IOException(
                        sm.getString("coyoteRequest.chunkedPostTooLarge"));
            }
            if (len > 0) {
                body.append(buffer, 0, len);
            }
        }
        if (body.getLength() == 0) {
            return null;
        }
        if (body.getLength() < body.getBuffer().length) {
            int length = body.getLength();
            byte[] result = new byte[length];
            System.arraycopy(body.getBuffer(), 0, result, 0, length);
            return result;
        }

        return body.getBuffer();
    }


public InputStream getStream() {
        if (inputStream == null) {
            inputStream = new CoyoteInputStream(inputBuffer);//之前已经关闭了
        }
        return inputStream;
    }



谢谢....
0 请登录后投票
   发表时间:2013-06-25  
池中物 写道
GET方式的请求参数在path中的。在解释http请求头的时候就能得到parameterMap了。
POST方式请求参数放在http消息主体中。在需要的时候(比如第一次getParameter)的时候才会去解释请求实体。

跟楼上说的一样,writer.close()的时候把request的输入给关闭了,导致无法从输入流中获取请求实体,因此无法得到parameterMap

你可以试试在new AjaxUtil("SUCCESS",response); 之前任意调用一下getParameter就正常。


是的,在调用new AjaxUtil("SUCCESS",response);之前调用 getParameter是正常的.
我昨天已经调试出这个问题了, 所以来发帖的. 楼上的几位已经贴出源码了, 明白原因了.
谢谢大家
0 请登录后投票
   发表时间:2013-06-25  
jinnianshilongnian 写道
我测试了下 jetty8 + tomcat6 木有问题,请问你的环境是什么

如果可以请给出demo,方便debug

不好意思。。。 忘了我开着filter了,不过我重新测试了下(servlet3)测试jetty8 没有问题的;

tomcat7是有问题的;和楼下说的原因一样;

在org.apache.catalina.connector.OutputBuffer
Request req = (Request) coyoteResponse.getRequest().getNote(
                CoyoteAdapter.ADAPTER_NOTES);
        req.inputBuffer.close();

一下是Request解析post body 代码
protected byte[] readChunkedPostBody() throws IOException {
        ByteChunk body = new ByteChunk();

        byte[] buffer = new byte[CACHED_POST_LEN];

        int len = 0;
        while (len > -1) {
            len = getStream().read(buffer, 0, CACHED_POST_LEN);
            if (connector.getMaxPostSize() > 0 &&
                    (body.getLength() + len) > connector.getMaxPostSize()) {
                // Too much data
                checkSwallowInput();
                throw new IOException(
                        sm.getString("coyoteRequest.chunkedPostTooLarge"));
            }
            if (len > 0) {
                body.append(buffer, 0, len);
            }
        }
        if (body.getLength() == 0) {
            return null;
        }
        if (body.getLength() < body.getBuffer().length) {
            int length = body.getLength();
            byte[] result = new byte[length];
            System.arraycopy(body.getBuffer(), 0, result, 0, length);
            return result;
        }

        return body.getBuffer();
    }


public InputStream getStream() {
        if (inputStream == null) {
            inputStream = new CoyoteInputStream(inputBuffer);//之前已经关闭了
        }
        return inputStream;
    }



根据楼上一位朋友的解释是,在response里面把inputStream给关闭了造成后面的getParameter取值不了
0 请登录后投票
   发表时间:2013-06-25  
ptma 写道
去看看 org.apache.catalina.connector 下的源码
response.getWriter().close() 的时候
有一句
req.inputBuffer.close();


正解, 谢谢
0 请登录后投票
   发表时间:2013-06-25  
jetty的木有这个问题。刚开始是用jetty测试的。
0 请登录后投票
   发表时间:2013-06-25  
额, 我用的是tomcat7
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics