java多次请求数据库_多次读取请求request里数据

如果请求是GET方法,可以直接通过getParameter(String param)方法读取指定参数,可读取多次;

而POST方法的参数是存储在输入流中,只能读一次,不能多次读取。

有时需要在filter里打印请求参数,因而在filter里读取post请求里的输入流后,会导致具体的controller里拿不到请求参数。

解决方法:

采用ThreadLocal,在filter里把读取到的post参数存入ThreadLocal里,而controller就可以再从ThreadLocal里把请求参数读取出来

使用servlet提供的HttpServletRequestWrapper类,重写相关ServletRequest方法,实现多次读取的能力

1.ThreadLocal方法

ThreadLocal实现:

public classThreadCache {

// ThreadLocal里只存储了简单的String对象,也可以自己定义对象,存储更加复杂的参数private static ThreadLocal threadLocal = new ThreadLocal();public staticString getPostRequestParams{returnthreadLocal.get();

}public static voidsetPostRequestParams(String postRequestParams){

threadLocal.set(postRequestParams);

}public static voidremovePostRequestParams(){

threadLocal.remove();

}

}

一个简单的filter:

importorg.apache.commons.io.IOUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;import javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;/*** Created by EndStart on 16/12/19.*/@WebFilter(value= {"/test/threadLocal/*"})public class SimpleFilter implementsFilter {private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);

@Overridepublic void init(FilterConfig filterConfig) throwsServletException {

}

@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throwsIOException, ServletException {

HttpServletRequest req=(HttpServletRequest) request;

HttpServletResponse res=(HttpServletResponse) response;try{if ("POST".equals(req.getMethod().toUpperCase())) {

// 获取请求参数byte[] bytes =IOUtils.toByteArray(request.getInputStream());

String params= newString(bytes, req.getCharacterEncoding());

ThreadCache.setPostRequestParams(params);

log.info("filer-post请求参数:[params={}]", params);

}else{

log.info("非post请求");

}

chain.doFilter(request, response);

}catch(Exception e) {

log.error(e.getMessage(), e);

}

}

@Overridepublic voiddestroy() {

}

}

简单的测试controller:

importcom.sankuai.xm.ems.auth.filter.ThreadCache;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.ResponseBody;/*** Created by Endstart on 16/12/19.*/@Controller

@RequestMapping("/test")public classTestController {private static Logger log = LoggerFactory.getLogger(TestController.class);

@RequestMapping(value= "/threadLocal/getPostRequestParams",method =RequestMethod.POST)

@ResponseBodypublic voidgetPostRequestParams() {

String params=ThreadCache.getPostRequestParams();

log.info("controller-post请求参数:[params={}]", params);

}

}

这里我们只保存了post参数,从ThreadLocal中反复读取,而get方法的还需要从request里获取;

2.HttpServletRequestWrapper方法

实现一个HttpServletRequestWrapper子类:

importorg.apache.commons.io.IOUtils;importjavax.servlet.ReadListener;importjavax.servlet.ServletInputStream;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletRequestWrapper;import java.io.*;/*** Created by Endstart on 16/11/30.*/

public class WrappedHttpServletRequest extendsHttpServletRequestWrapper {private byte[] bytes;privateWrappedServletInputStream wrappedServletInputStream;public WrappedHttpServletRequest(HttpServletRequest request) throwsIOException {super(request);//读取输入流里的请求参数,并保存到bytes里

bytes =IOUtils.toByteArray(request.getInputStream());

ByteArrayInputStream byteArrayInputStream= newByteArrayInputStream(bytes);this.wrappedServletInputStream = newWrappedServletInputStream(byteArrayInputStream);

// 很重要,把post参数重新写入请求流reWriteInputStream();

}/*** 把参数重新写进请求里*/

public voidreWriteInputStream() {

wrappedServletInputStream.setStream(new ByteArrayInputStream(bytes != null ? bytes : new byte[0]));

}

@Overridepublic ServletInputStream getInputStream() throwsIOException {returnwrappedServletInputStream;

}

@Overridepublic BufferedReader getReader() throwsIOException {return new BufferedReader(newInputStreamReader(wrappedServletInputStream));

}/*** 获取post参数,可以自己再转为相应格式*/

public String getRequestParams() throwsIOException {return new String(bytes, this.getCharacterEncoding());

}private class WrappedServletInputStream extendsServletInputStream {public voidsetStream(InputStream stream) {this.stream =stream;

}privateInputStream stream;publicWrappedServletInputStream(InputStream stream) {this.stream =stream;

}

@Overridepublic int read() throwsIOException {returnstream.read();

}

@Overridepublic booleanisFinished() {return true;

}

@Overridepublic booleanisReady() {return true;

}

@Overridepublic voidsetReadListener(ReadListener readListener) {

}

}

}

实现另一个filter:

importcom.sankuai.xm.ems.utils.wrap.WrappedHttpServletRequest;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;import javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjava.io.IOException;/*** Created by EndStart on 16/12/19.*/@WebFilter(value= {"/test/wrapped/*"})public class SimpleWrappedFilter implementsFilter {private static Logger log = LoggerFactory.getLogger(SimpleWrappedFilter.class);

@Overridepublic void init(FilterConfig filterConfig) throwsServletException {

}

@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throwsIOException, ServletException {try{

WrappedHttpServletRequest requestWrapper= newWrappedHttpServletRequest((HttpServletRequest) request);if ("POST".equals(requestWrapper.getMethod().toUpperCase())) {

// 获取请求参数

String params=requestWrapper.getRequestParams();

log.info("filer-post请求参数:[params={}]", params);

}else{

log.info("非post请求");

}//这里doFilter传入我们实现的子类

chain.doFilter(requestWrapper, response);

}catch(Exception e) {

log.error(e.getMessage(), e);

}

}

@Overridepublic voiddestroy() {

}

}

我们在上面的TestController里加入一个新的处理方法:

@RequestMapping(value = "/wrapped/getPostRequestParams",method =RequestMethod.POST)

@ResponseBody//public void getPostRequestParams(@RequestBody String params) {

public void getPostRequestParams(HttpServletRequest request) throwsException{byte[] bytes =IOUtils.toByteArray(request.getInputStream());

String params= newString(bytes, request.getCharacterEncoding());

log.info("controller-post请求参数:[params={}]", params);

}

这种方法里,我们在SimpleWrappedFilter里一个实现了WrappedHttpServletRequest类,其构造器自动读取了servletRequest里的输入流,并把数据保存了下来,最后又把数据重新写入servletRequest里,使得cotroller可以再次从request里读取到输入参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值