注入 MultivaluedMap 的注入提供程序 (application/x-www-form-urlencoded)

Injection provider with injected MultivaluedMap (application/x-www-form-urlencoded)

Jersey 文档给出了一个 how to inject HttpSession on resources. How should I inject (or otherwise gain access to) form parameters sent on requests with "Content-Type: application/x-www-form-urlencoded"? I see that these are passed as parameters on methods, and do not seem to be annotated 的例子,让我相信这里有一些怪癖?

我目前正在使用的(幼稚的)工厂实现如下,JerseyHttpServletRequestWrapper 是我自己的工厂之一 类:

import org.glassfish.hk2.api.Factory;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MultivaluedMap;

public class JerseyHttpServletRequestWrapperFactory implements Factory<JerseyHttpServletRequestWrapper> {
    private final HttpServletRequest request;
    private final MultivaluedMap<String, String> formParams;

    @Inject
    public JerseyHttpServletRequestWrapperFactory(HttpServletRequest request, MultivaluedMap<String, String> formParams) {
        this.request = request;
        this.formParams = formParams;
    }

    @Override
    public JerseyHttpServletRequestWrapper provide() {
        return new JerseyHttpServletRequestWrapper(request, formParams);
    }

    @Override
    public void dispose(JerseyHttpServletRequestWrapper jerseyHttpServletRequestWrapper) {
    }
}

我在这里考虑应该将一个实体提供者注入到实例中,这样我就可以检查是否确实有一个实体随请求一起发送。尝试直接注入 MultivaluedMap 错误:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=MultivaluedMap<String,String>,parent=JerseyHttpServletRequestWrapperFactory,qualifiers={},position=1,optional=false,self=false,unqualified=null,2067821943)

当你这样做时

@POST
public Response post(MultivaluedMap<String, String> params) {}

此方法参数注入的处理方式与常规 field/constructor 注入不同。所以你不能尝试将 MultivaluedMap 注入字段。

不过你可以做的是注入 ContainerRequest,然后阅读正文。您需要检查它是一个 POST 请求并且 Content-Type 是 application/x-www-form-urlencoded。否则,当您尝试读取实体时,您可能会遇到异常。

@Inject
ContainerRequest request;

if (request.getMethod().toUpperCase().equals("POST")
     && request.getMediaType().equals(MediaType.APPLICATION_FORM_URLENCODED_TYPE)) {
    request.bufferEntity();
    Form form = request.readEntity(Form.class);
    MultivaluedMap<String, String> params = form.asMap();
}