0

我正在试验 api verioning 并且有一个非常特殊的要求来解决。我们将为此使用内容协商,即 @Produces 注释,我想要一个格式为 @Produces({"th/v1-v10+xml"}) 的自定义媒体类型,其中 v1-v10 告诉这个 api将服务任何带有“th/v1+xml”、“th/v2+xml”的Accept标头的请求,一直到“th/v10+xml”。

我知道这有点奇怪,但我们的想法是,我们在生产中所做的每个 drop 都将是客户端的新版本,但并非每个服务都会被修改。所以我想用一个范围来注释服务,这样我就不必为每一滴都复制它,即使它没有改变。

所以我想知道有什么方法可以在匹配@Path 和@Produces 注释的同时拦截Jersey 中的登录?我知道我不能使用正则表达式来匹配媒体类型。

…………

更多研究告诉我,Jersey 调用 MediaType.isCompatible(MediaType other) 方法来确定请求接受标头和服务提供者媒体类型之间的兼容性。

如果我可以创建自定义 MediaType 并覆盖 isCompatible 方法,则可以稍微利用这一点。泽西岛是否允许这样的扩展?

任何帮助深表感谢。

4

1 回答 1

0

您可能必须使用自定义响应映射器。

1.- 创建一个实现 MessageBodyWriter 的类,负责编写响应

@Provider
public class MyResponseTypeMapper 
  implements MessageBodyWriter<MyResponseObjectType> {
     @Override
     public boolean isWriteable(final Class<?> type,final Type genericType,
                final Annotation[] annotations,
                final MediaType mediaType) {
       ... use one of the arguments (either the type, an annotation or the MediaType)
           to guess if the object shoud be written with this class
     }
     @Override
     public long getSize(final MyResponseObjectType myObjectTypeInstance,
                     final Class<?> type,final Type genericType,
                         final Annotation[] annotations,
                     final MediaType mediaType) {
        // return the exact response length if you know it... -1 otherwise
        return -1;
    }
    @Override
    public void writeTo(final MyResponseObjectType myObjectTypeInstance,
                    final Class<?> type,final Type genericType,
                    final Annotation[] annotations, 
                    final MediaType mediaType,
                    final MultivaluedMap<String,Object> httpHeaders,
                    final OutputStream entityStream) throws IOException,                                                                 WebApplicationException {
        ... serialize / marshall the MyResponseObjectType instance using
            whatever you like (jaxb, etC)
        entityStream.write(serializedObj.getBytes());
    }
}

2.- 在您的应用中注册映射器

public class MyRESTApp 
     extends Application  {
    @Override
public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(MyResponseTypeMapper.class);
        return s;
    }
}

Jersey 将扫描所有已注册的调用其 isWriteable() 方法的映射器,直到一个返回 true...如果是这样,此 MessageBodyWriter 实例将用于将内容序列化到客户端

于 2013-05-27T00:04:13.927 回答