我正在尝试为我的restful服务创建一个自定义的http param绑定.请参阅下面的示例.
@POST
@Path("/user/{userId}/orders")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public MyResult foo(@PathParam("userId") String someString, @UserAuthHeaderParam String authString){
}
Run Code Online (Sandbox Code Playgroud)
您可以看到函数签名中有UserAuthHeaderParam注释.我想要做的是有一个自定义的http param绑定,而不是标准的javax.ws.rs.*Param.
我试图实现org.glassfish.hk2.api.InjectionResolver,它基本上从http头中提取值:
public class ProtoInjectionResolver implements InjectionResolver<UserAuthHeaderParam>{
...
@Override
public Object resolve(Injectee injectee, ServiceHandle< ? > root)
{
return "Hello World";
}
...
}
Run Code Online (Sandbox Code Playgroud)
当我调用restful服务时,服务器会遇到异常.它表明框架无法解析函数签名中的参数:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=String,parent=MyResource,qualifiers={}),position=0,optional=false,self=false,unqualified=null,2136594195),
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of rs.server.MyResource errors were found
Run Code Online (Sandbox Code Playgroud)
请帮忙.任何建议表示赞赏.我在谷歌上做了很多搜索,但未能使它工作.泽西岛2.*.如何替换Jersey 1.*的InjectableProvider和AbstractHttpContextInjectable可能是类似的问题.
- 更新:我使用AbstractBinder将我的解析器绑定到UserAuthHeaderParam:
public class MyApplication extends ResourceConfig
{
public MyApplication()
{
register(new AbstractBinder() …Run Code Online (Sandbox Code Playgroud) 我有一个像以下的功能:
@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)
我仍然很高兴知道是否有更好的方法来做到这一点,所以我现在暂时打开这个问题.
我从他对这个问题[ 1 ]的答案中听取了Michal的指南,该问题涉及实现自定义注释以将任意事物注入资源方法.这个(要点)[ 2 ]包含一个从jersey-quickstart-grizzly2原型改编而来的简约试验台.我将在下文中提及它.
我遇到了一些问题:
我的解析器是参数化类型(或者至少它会让事情变得更加清洁,在我看来)因此我不能bind像Michal所说的那样在我的活页夹中.
// Instead of the suggested:
// bind(MyInjectionResolver.class).to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {}).in(Singleton.class);
// I do:
bind(myInjectionResolverObject).to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {});
Run Code Online (Sandbox Code Playgroud)当我MyAnnotation在资源方法中使用时,我在服务器启动时收到以下警告(但服务器仍然启动):
WARNING: The following warnings have been detected: WARNING: A HTTP GET method, public java.lang.String com.example.MyResource.get02(java.lang.Integer,java.lang.String), should not consume any entity.
Run Code Online (Sandbox Code Playgroud)当我请求resource(curl -X GET http://localhost:8080/myresource/01/aa)时,我得到的02: value = aa; providedValue = null不是预期的02: value = aa; providedValue = 123.
该MyResolver.resolve方法永远不会执行(但会MyBinder.configure被执行).
(这与测试平台应用程序无关,但我在稍微复杂的代码中遇到了问题:资源方法永远不会执行,服务器会响应500 No content …