springmvc的参数接收不能兼容以及HttpServletRequest中的流多次使用
2018-01-31 11:44
489 查看
web开发中的POST请求很常见,最近遇到的一个问题是写接口,我看别人牛逼的接口都是又能浏览器访问,又能JS访问,又能URL getUrl = new URL(url);URLConnection connection = getUrl.openConnection();访问,
而我在用springmvc的时候利用他请求参数自动封装的用法,怎么样都不能兼容JS和后台请求接口两种用法,也是百度谷歌半天无果,最后我看我java发起的post请求,写法如下:
OutputStream out = conn.getOutputStream();
out.write((jsonObj.toString()).getBytes("UTF-8"));
这就是输出流,对于服务端来说就是要接收这个输出流啊,springmvc的什么表单或者json参数自动封装成对象,或者各种接收参数的注解,其实都是封装HttpServletRequest中的流。
既然这样,那就不用springmvc的自动封装了,自己封装。
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
这样就能获取到HttpServletRequest中的post数据了,sb.toString(),一般是json格式,至于json格式想得到对应类型的数据就很随意了。
这里要注意的是:在正常开发中,HttpServletRequest这个参数需要经过多个过滤器,而无法保证在哪个过滤器的操作中被读取了一次流的操作,只能读取一次,读取了一次后面从过滤器到达controller的时候再获取是null的。
那么解决这个问题的办法也有多个,这里说一个算是比较简单的做法
1、创建类:ThreadCache
public class ThreadCache {
// ThreadLocal里只存储了简单的String对象,也可以自己定义对象,存储更加复杂的参数
private static ThreadLocal<String> threadLocal = new ThreadLocal<String>();
public static String getPostRequestParams() {
return threadLocal.get();
}
public static void setPostRequestParams(String postRequestParams) {
threadLocal.set(postRequestParams);
}
public static void removePostRequestParams() {
threadLocal.remove();
}
}
2、在过滤器中将以上读取流的代码进行改造一下
if ("POST".equals(req.getMethod().toUpperCase())) {
BufferedReader br = new BufferedReader(new InputStreamReader(
(ServletInputStream) request.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
//将流放在线程里面,在controller中需要重复利用,如果不这样controller中request带的post数据将会丢失
ThreadCache.setPostRequestParams(sb.toString());
}
3、到请求最终需要参数的地方获取参数,比如springmvc中的controller里面
String requestStr = ThreadCache.getPostRequestParams();
requestStr 就是请求的json参数。
而我在用springmvc的时候利用他请求参数自动封装的用法,怎么样都不能兼容JS和后台请求接口两种用法,也是百度谷歌半天无果,最后我看我java发起的post请求,写法如下:
OutputStream out = conn.getOutputStream();
out.write((jsonObj.toString()).getBytes("UTF-8"));
这就是输出流,对于服务端来说就是要接收这个输出流啊,springmvc的什么表单或者json参数自动封装成对象,或者各种接收参数的注解,其实都是封装HttpServletRequest中的流。
既然这样,那就不用springmvc的自动封装了,自己封装。
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
这样就能获取到HttpServletRequest中的post数据了,sb.toString(),一般是json格式,至于json格式想得到对应类型的数据就很随意了。
这里要注意的是:在正常开发中,HttpServletRequest这个参数需要经过多个过滤器,而无法保证在哪个过滤器的操作中被读取了一次流的操作,只能读取一次,读取了一次后面从过滤器到达controller的时候再获取是null的。
那么解决这个问题的办法也有多个,这里说一个算是比较简单的做法
1、创建类:ThreadCache
public class ThreadCache {
// ThreadLocal里只存储了简单的String对象,也可以自己定义对象,存储更加复杂的参数
private static ThreadLocal<String> threadLocal = new ThreadLocal<String>();
public static String getPostRequestParams() {
return threadLocal.get();
}
public static void setPostRequestParams(String postRequestParams) {
threadLocal.set(postRequestParams);
}
public static void removePostRequestParams() {
threadLocal.remove();
}
}
2、在过滤器中将以上读取流的代码进行改造一下
if ("POST".equals(req.getMethod().toUpperCase())) {
BufferedReader br = new BufferedReader(new InputStreamReader(
(ServletInputStream) request.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
//将流放在线程里面,在controller中需要重复利用,如果不这样controller中request带的post数据将会丢失
ThreadCache.setPostRequestParams(sb.toString());
}
3、到请求最终需要参数的地方获取参数,比如springmvc中的controller里面
String requestStr = ThreadCache.getPostRequestParams();
requestStr 就是请求的json参数。
相关文章推荐
- JQuery中Ajax的Post提交中文乱码、windows.location.href 中文汉字乱码和springmvc使用原生态HttpServletRequest接收参数中文乱码解决办法
- 如何使用Ajax(XMLHttpRequest)发送带参数的请求,以及如何在Servlet中获取请求中的参数
- Model model,HttpServletRequest request, ModelMap map参数使用与区别
- SpringMVC项目使用HttpServletRequest
- springMVC使用multipartFile上传文件出错:MultipartHttpServletRequest: is a MultipartResolver configured?
- HttpServletRequest getParameter 接收get方式传递的中文参数(tomcat8.5)
- 使用HttpServletRequestWrapper在filter修改request参数
- springmvc 使用 @RequestBody接收参数
- HttpServletRequest.getInputStream可读取多次解决方案之一,使用HttpServletRequestWrapper
- springmvc使用HttpServletRequest
- HttpServletRequest&&HttpServletResponse参数的接收和响应
- HttpServletRequest接收参数的几种方法
- springMVC使用multipartFile上传文件出错:MultipartHttpServletRequest: is a MultipartResolver configured?
- HttpServletRequest getParameterValues 接收get/post方式传递的多值参数
- 关于在struts2中interceptor 中使用ActionInvocation 对象获得HttpServletRequest中封装的参数,以Map的形式
- SpringMVC——使用RequestDispatcher.include()和HttpServletResponseWrapper动态获取jsp输出内容
- SpringMVC参数传递 HttpServletRequest,HttpServletResponse和HttpSession
- 使用JavaScript的XMLHttpRequest发送POST、GET请求以及接收返回值
- SpringMVC上传图片总结(1)---常规方法进行图片上传,使用了MultipartFile、MultipartHttpServletRequest
- 使用JavaScript的XMLHttpRequest发送POST、GET请求以及接收返回值