在Jersey中,我可以将QueryParams和FormParams组合成一个方法的值吗?

Wil*_*ver 6 java jax-rs jersey

我有一个像以下的功能:

@POST
@Path("/create")
@Produces({MediaType.APPLICATION_JSON})
public Playlist createPlaylist(@FormParam("name") String name)
{
    Playlist p = playlistDao.create();
    p.setName(name);
    playlistDao.insert(p);
    return p;
}
Run Code Online (Sandbox Code Playgroud)

我希望"name"参数来自查询参数的形式OR.如果用户发布到/ playlist/create /?name = bob,那么我希望它能够正常工作.(这主要是为了帮助测试API,还有助于在不同的非浏览器平台上使用它.)

我愿意将魔术绑定工作的子类化(... @BothParam("name")字符串名称),但需要一些帮助才能实现,因为我是Jersey/Java Servlets的新手.


更新:第二天......

我通过实现一个将表单参数合并到查询参数中的ContainerRequestFilter来解决这个问题.这不是最好的解决方案,但似乎确实有效.我没有任何运气将任何内容合并到表单参数中.

这是代码,以防有人来找它:

@Override
public ContainerRequest filter(ContainerRequest request) 
{
    MultivaluedMap<String, String> qParams = request.getQueryParameters();
    Form fParams = request.getFormParameters();
    for(String key : fParams.keySet())
    {
        String value = fParams.get(key).get(0);
        qParams.add(key, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

我仍然很高兴知道是否有更好的方法来做到这一点,所以我现在暂时打开这个问题.

max*_*der 3

实现此目的的一种方法是使用InjectableProvider.

首先,您需要定义一个BothParam注释:

@Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface BothParam { String value(); }
Run Code Online (Sandbox Code Playgroud)

然后,InjectableProvider为其定义一个:

@Provider
public class BothParamProvider implements Injectable<String>, InjectableProvider<BothParam, Type> {    
    @Context private HttpContext httpContext;
    private String parameterName;

    public BothParamProvider(@Context HttpContext httpContext) {
        this.httpContext = httpContext;
    }

    public String getValue() {        
        if (httpContext.getRequest().getQueryParameters().containsKey(parameterName)) {
            return httpContext.getRequest().getQueryParameters().getFirst(parameterName);
        } else if(httpContext.getRequest().getFormParameters().containsKey(parameterName)) {
            return httpContext.getRequest().getFormParameters().getFirst(parameterName);
        }
        return null;
    }

    public ComponentScope getScope() {
        return ComponentScope.PerRequest;
    }

    public Injectable getInjectable(ComponentContext cc, BothParam a, Type c) {        
        parameterName = a.value();
        return this;
    }    
}
Run Code Online (Sandbox Code Playgroud)

QueryParam请注意,这并不是真正的和耦合FormParam。用其中任何一个注释的目标都会以更复杂的方式注入。但是,如果您的需求足够有限,上述方法可能适合您。