在HTTP Post请求中同时发送查询字符串和JSON主体到服务器是可能的,这是我已经理解的。为此,我们需要覆盖HttpServletRequestWrapper类的getReader和getInputstream方法。我已经按照这篇link中的研究做了这件事。在Stack Overflow中也看到了类似的答案。
因此,现在我有一个登录操作,其中没有主体,只有post中的查询字符串params。当我尝试读取它们时,getParameter()的输出结果为null。在我的包装器中,我打印捕获的正文,它正确地显示了从客户机接收到的正确数据。
在从HTTP读取时使用的读取查询字符串(getParameter()
)和JSON body (gson.fromJson)的简单方法也可以用于包装的unWrapped请求吗?这里我漏掉了什么?
servlet的POST方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("from doPost");
RequestWrapper wrappedrequest = new RequestWrapper(request);
request = wrappedrequest;
String action= request.getParameter("action");
if(action.equals("update")) {
Gson gson = new Gson();
Order cart = gson.fromJson(request.getReader(), Order.class);
CartDao dao= new CartDao(cart);
dao.addData();
}else if(action.equals("login")) {
loginDao ld = new loginDao(request);
int roleId = ld.authenticate();
if(roleId!=-1) {
System.out.println("Role ID Got is "+ roleId);
HttpSession session = ld.loadSession(roleId);
System.out.println("Init page for logging in user is = "+ session.getAttribute("initPage").toString());
CartDao dao= new CartDao();
JsonArray responseJson= dao.getOrderList();
request.setAttribute("ResponseJson", responseJson);
RequestDispatcher rq = request.getRequestDispatcher(session.getAttribute("initPage").toString());
rq.forward(request, response);
}else {
request.setAttribute("errmsg", "Invalid username/password");
RequestDispatcher rq = request.getRequestDispatcher("login.jsp");
rq.forward(request, response);
}
}else {
System.out.println("No Action");
}
}
RequestWrapper
public class RequestWrapper extends HttpServletRequestWrapper {
private String _body;
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
_body = "";
BufferedReader bufferedReader = request.getReader();
String line;
while ((line = bufferedReader.readLine()) != null){
_body += line; //when i print this it shows proper data got from client machine
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes());
return new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setReadListener(ReadListener arg0) {
// TODO Auto-generated method stub
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
发布于 2018-06-10 02:44:27
最终我自己破解了这个问题。我所要做的就是读取查询字符串,并将其保存在映射中,然后通过在getParameter覆盖的方法中获取键来返回值。通过读取输入流来保存主体,并在调用被覆盖的getReader时返回主体。这个函数可以被调用任意次数。:)虽然这行得通,但如果有人能详细解释一下为什么行得通,那就太好了。
执行此魔法的Star代码如下所示:
public class RequestWrapper extends HttpServletRequestWrapper {
private String _body;
private String _queryString;
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
_body = "";
BufferedReader bufferedReader = request.getReader();
String line;
while ((line = bufferedReader.readLine()) != null){
_body += line;
}
_queryString = request.getQueryString();
System.out.println(_body + _queryString);
}
}
https://stackoverflow.com/questions/50772512
复制相似问题