使用 HTTPServletRequestWrapper 包装请求参数
Posted
技术标签:
【中文标题】使用 HTTPServletRequestWrapper 包装请求参数【英文标题】:Wrapping request parameters using HTTPServletRequestWrapper 【发布时间】:2013-05-26 17:42:06 【问题描述】:我有一个过滤器来验证/授权 REST 调用。这个过滤器需要访问请求参数,所以我为此编写了一个自定义 HTTPServletRequestWrapper。
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class WrapperRequest extends HttpServletRequestWrapper
private Map<String, String[]> requestParams = null;
public WrapperRequest(final ServletRequest request)
super((HttpServletRequest) request);
@Override
public String getParameter(final String name)
if (getParameterMap().get(name) != null)
return getParameterMap().get(name)[0];
else
getParameterMap().get(name)[0] = super.getParameter(name);
requestParams.put(name, getParameterMap().get(name));
return requestParams.get(name)[0];
@Override
public Map<String, String[]> getParameterMap()
if (requestParams == null)
requestParams = new HashMap<String, String[]>();
requestParams.putAll(super.getParameterMap());
return Collections.unmodifiableMap(requestParams);
@Override
public Enumeration<String> getParameterNames()
return Collections.enumeration(getParameterMap().keySet());
@Override
public String[] getParameterValues(final String name)
return getParameterMap().get(name);
在我的过滤器doFilter方法中:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
final WrapperRequest wrappedRequest = new WrapperRequest(request);
Map<String, String[]> paramMap = wrappedRequest.getParameterMap();
chain.doFilter(wrappedRequest, response);
但我收到以下警告
警告:对 URI 的 servlet 请求 , 包含形式 请求正文中的参数,但请求正文已被消耗 通过 servlet 或 servlet 过滤器访问请求参数。 只有使用 @FormParam 的资源方法才能按预期工作。资源 通过其他方式使用请求正文的方法将无法正常工作 预计。
我在 Tomcat 中部署它。救命!
【问题讨论】:
【参考方案1】:没错。所以我一直遇到这个问题,我一直在尝试以不同的方式解决它,但我不想更改我的 web.xml 设置,只是因为如果我用 Postman 测试我的应用程序,它工作得很好,但是当它与 webapp 集成时,它会因上述问题而失败 (A servlet request to the URI MY_URI contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.
)
正如@clijk 提到的,您只需将标题设置为:
"Content-Type": "application/json"
"charset": "UTF-8"
瞧,警告消失了。
谢谢
【讨论】:
【参考方案2】:我认为您将 Jersey 用于您的 REST 框架?
我认为这基本上是说,由于 Servlet 现在已经构造了 Request 对象,Jersey 现在无法区分表单参数和查询字符串参数。
有关详细信息,请参阅此:https://issues.apache.org/jira/browse/STANBOL-437
这引出了一个问题 - 这实际上是给您带来问题还是您只是担心警告消息?
【讨论】:
好的,谢谢!这里没有问题。这只是一个警告。以上是关于使用 HTTPServletRequestWrapper 包装请求参数的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)