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

时间:2012-01-04 00:47:02

标签: java jersey jax-rs

我的功能如下:

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

我希望“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);
    }
}

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

1 个答案:

答案 0 :(得分:3)

一种方法是使用InjectableProvider

首先,您要定义BothParam注释:

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

然后,为它定义一个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;
    }    
}

注意,这不是QueryParamFormParam的真正耦合。用其中任何一个注释的目标都以更复杂的方式注入。但是,如果您的需求受到足够的限制,上面概述的方法可能对您有用。