我正在尝试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方法,则可能能够利用这一点。泽西岛是否允许这样的延期??
非常感谢任何帮助。
答案 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实例将用于将内容序列化到客户端