如何在HttpServletRequest中设置参数?

Alc*_*sta 28 java web-applications

我正在使用javax.servlet.http.HttpServletRequest来实现Web应用程序.

使用getParameter方法获取请求的参数没有问题.但是我不知道如何在我的请求中设置参数.

ska*_*man 29

你不能,不使用标准API.HttpServletRequest表示服务器收到的请求,因此添加新参数不是有效选项(就API而言).

原则上,您可以实现HttpServletRequestWrapper包装原始请求的子类,并拦截getParameter()方法,并在转发时传递包装的请求.

如果你走这条路,你应该使用a Filter替换你HttpServletRequestHttpServletRequestWrapper:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    if (servletRequest instanceof HttpServletRequest) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // Check wether the current request needs to be able to support the body to be read multiple times
        if (MULTI_READ_HTTP_METHODS.contains(request.getMethod())) {
            // Override current HttpServletRequest with custom implementation
            filterChain.doFilter(new HttpServletRequestWrapper(request), servletResponse);
            return;
        }
    }
    filterChain.doFilter(servletRequest, servletResponse);
}
Run Code Online (Sandbox Code Playgroud)

  • 我假设您从[here](http://stackoverflow.com/questions/1046721/accessing-the-raw-body-of-a-put-or-post-request)获得了此实现.MULTI_READ_HTTP_METHODS有点令人困惑,虽然现在我明白它的用途是什么,但我要求你完全删除它. (2认同)

Jef*_*ams 20

如果您真的想这样做,请创建一个HttpServletRequestWrapper.

public class AddableHttpRequest extends HttpServletRequestWrapper {

   private HashMap params = new HashMap();

   public AddableingHttpRequest(HttpServletRequest request) {
           super(request);
   }

   public String getParameter(String name) {
           // if we added one, return that one
           if ( params.get( name ) != null ) {
                 return params.get( name );
           }
           // otherwise return what's in the original request
           HttpServletRequest req = (HttpServletRequest) super.getRequest();
           return validate( name, req.getParameter( name ) );
   }

   public void addParameter( String name, String value ) {
           params.put( name, value );
   }

}
Run Code Online (Sandbox Code Playgroud)

  • 只需将其替换为 - return req.getParameter(name); (4认同)
  • 方法验证的作用是什么? (3认同)

Mau*_*bon 15

从你的问题来看,我认为你要做的是存储一些东西(一个对象,一个字符串......)然后使用RequestDispatcher()将它转移到另一个servlet.要做到这一点,您不需要设置参数,而是使用属性

void setAttribute(String name, Object o);
Run Code Online (Sandbox Code Playgroud)

然后

Object getAttribute(String name);
Run Code Online (Sandbox Code Playgroud)

  • 属性和参数不可互换,并且代表了非常不同的概念. (7认同)
  • 对不起,如果我的问题不够清楚,但我真正想知道的是,如果可以设置参数而不是属性,这就是我接受skaffman答案的原因.但是,你的答案很好,可能会帮助其他人:-) (4认同)
  • @skaffman但也许他可以使用属性解决他需要的东西 - 在处理请求的过程中不需要为请求添加新参数 (2认同)
  • 应该编辑答案以反映设置属性可能是问题的解决方案,而不是暗示设置属性在请求中设置参数. (2认同)

Dex*_*spi 6

最受支持的解决方案通常有效,但对于 Spring 和/或 Spring Boot,这些值不会连接到带有注释的控制器方法中的参数,@RequestParam除非您专门实现了getParameterValues(). 我结合了此处和此博客中的解决方案:

import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MutableHttpRequest extends HttpServletRequestWrapper {

    private final Map<String, String[]> mutableParams = new HashMap<>();

    public MutableHttpRequest(final HttpServletRequest request) {
        super(request);
    }

    public MutableHttpRequest addParameter(String name, String value) {
        if (value != null)
            mutableParams.put(name, new String[] { value });

        return this;
    }

    @Override
    public String getParameter(final String name) {
        String[] values = getParameterMap().get(name);

        return Arrays.stream(values)
                .findFirst()
                .orElse(super.getParameter(name));
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> allParameters = new HashMap<>();
        allParameters.putAll(super.getParameterMap());
        allParameters.putAll(mutableParams);

        return Collections.unmodifiableMap(allParameters);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(getParameterMap().keySet());
    }

    @Override
    public String[] getParameterValues(final String name) {
        return getParameterMap().get(name);
    }
}

Run Code Online (Sandbox Code Playgroud)

请注意,此代码并未经过超级优化,但它可以工作。