@ Produces / provider媒体类型匹配

时间:2012-09-14 11:11:16

标签: jersey

我正在尝试api verioning并且有一个非常特殊的要求来对抗。我们将使用内容协商,即@Produces注释,我希望以@Produces({“th / v1-v10 + xml”})等格式自定义媒体类型,其中v1-v10告诉我这个api将使用Accept标题“th / v1 + xml”,“th / v2 + xml”一直提供给“th / v10 + xml”的任何请求。

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

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

.......

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

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分: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.-在您的应用中注册Mappers

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

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