簡體   English   中英

如何在 HttpServletRequest 中設置參數?

[英]How to set a parameter in a HttpServletRequest?

我正在使用javax.servlet.http.HttpServletRequest來實現一個 web 應用程序。

使用getParameter方法獲取請求的參數沒有問題。 但是我不知道如何在我的請求中設置參數。

你不能,不使用標准 API。 HttpServletRequest代表服務器收到的請求,因此添加新參數不是有效的選項(就 API 而言)。

原則上,您可以實現HttpServletRequestWrapper的子類,它包裝原始請求,並攔截getParameter()方法,並在轉發時傳遞包裝的請求。

如果你走這條路,你應該使用FilterHttpServletRequest替換你的HttpServletRequestWrapper

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);
}

如果您真的想這樣做,請創建一個 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 );
   }

}

從你的問題來看,我認為你想要做的是使用 RequestDispatcher() 存儲一些東西(一個對象,一個字符串......)然后將它轉發到另一個 servlet。 為此,您不需要設置參數,而是使用屬性

void setAttribute(String name, Object o);

接着

Object getAttribute(String name);

正如在之前的帖子中提到的,使用 HttpServletReqestWrapper 是可行的方法,但是這些帖子中遺漏的部分是除了覆蓋方法 getParameter() 之外,您還應該覆蓋其他與參數相關的方法以產生一致的響應。 例如,自定義請求包裝器添加的參數值也應包含在方法 getParameterMap() 返回的參數映射中。 下面是一個例子:

   public class AddableHttpRequest extends HttpServletRequestWrapper {

    /** A map containing additional request params this wrapper adds to the wrapped request */
    private final Map<String, String> params = new HashMap<>();

    /**
     * Constructs a request object wrapping the given request.
     * @throws java.lang.IllegalArgumentException if the request is null
     */
    AddableHttpRequest(final HttpServletRequest request) {
        super(request)
    }

    @Override
    public String getParameter(final String name) {
        // if we added one with the given name, return that one
        if ( params.get( name ) != null ) {
            return params.get( name );
        } else {
            // otherwise return what's in the original request
            return super.getParameter(name);
        }
    }


    /**
     * *** OVERRIDE THE METHODS BELOW TO REFLECT PARAMETERS ADDED BY THIS WRAPPER ****
     */

    @Override
    public Map<String, String> getParameterMap() {
        // defaulf impl, should be overridden for an approprivate map of request params
        return super.getParameterMap();
    }

    @Override
    public Enumeration<String> getParameterNames() {
        // defaulf impl, should be overridden for an approprivate map of request params names
        return super.getParameterNames();
    }

    @Override
    public String[] getParameterValues(final String name) {
        // defaulf impl, should be overridden for an approprivate map of request params values
        return super.getParameterValues(name);
    }
}

最受好評的解決方案通常有效,但對於 Spring 和/或 Spring Boot,除非您專門實現了getParameterValues()否則這些值不會連接到用@RequestParam注釋的控制器方法中的參數。 我結合了這里和這個博客的解決方案:

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);
    }
}

請注意,此代碼並未經過超級優化,但可以正常工作。

丟失的 getParameterMap 覆蓋最終對我來說是一個真正的問題。 所以這就是我最終的結果:

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/***
 * Request wrapper enabling the update of a request-parameter.
 * 
 * @author E.K. de Lang
 *
 */
final class HttpServletRequestReplaceParameterWrapper
    extends HttpServletRequestWrapper
{

    private final Map<String, String[]> keyValues;

    @SuppressWarnings("unchecked")
    HttpServletRequestReplaceParameterWrapper(HttpServletRequest request, String key, String value)
    {
        super(request);

        keyValues = new HashMap<String, String[]>();
        keyValues.putAll(request.getParameterMap());
        // Can override the values in the request
        keyValues.put(key, new String[] { value });

    }

    @SuppressWarnings("unchecked")
    HttpServletRequestReplaceParameterWrapper(HttpServletRequest request, Map<String, String> additionalRequestParameters)
    {
        super(request);
        keyValues = new HashMap<String, String[]>();
        keyValues.putAll(request.getParameterMap());
        for (Map.Entry<String, String> entry : additionalRequestParameters.entrySet()) {
            keyValues.put(entry.getKey(), new String[] { entry.getValue() });
        }

    }

    @Override
    public String getParameter(String name)
    {
        if (keyValues.containsKey(name)) {
            String[] strings = keyValues.get(name);
            if (strings == null || strings.length == 0) {
                return null;
            }
            else {
                return strings[0];
            }
        }
        else {
            // Just in case the request has some tricks of it's own.
            return super.getParameter(name);
        }
    }

    @Override
    public String[] getParameterValues(String name)
    {
        String[] value = this.keyValues.get(name);
        if (value == null) {
            // Just in case the request has some tricks of it's own.
            return super.getParameterValues(name);
        }
        else {
            return value;
        }
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        return this.keyValues;
    }

}

抱歉,為什么不使用以下結構:

request.getParameterMap().put(parameterName, new String[] {parameterValue});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM