泽西岛更新实体属性MessageBodyWriter [英] Jersey Update Entity Property MessageBodyWriter
问题描述
我想创建一个Jersey提供程序( MessageBodyWriter )更新dto对象属性,并继续将链链接到Jersey-json默认提供程序,并返回json对象. 问题是,看起来好像没有调用默认提供程序,所以我注册新的提供程序后,我的其余服务的输出就为空.
I want to create a Jersey provider (MessageBodyWriter) that update a dto object property and continue the chain to Jersey-json default provider an return the json object. the problem is that looks like default provider is not called so the output of my rest service become empty as soon as I register the new Provider.
@Provider
public class TestProvider implements MessageBodyWriter<MyDTO>
{
@Override
public long getSize(
MyDTO arg0, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4)
{
return 0;
}
@Override
public boolean isWriteable(Class<?> clazz, Type type, Annotation[] arg2, MediaType arg3)
{
return type == MyDTO.class;
}
@Override
public void writeTo(
MyDTO dto,
Class<?> paramClass,
Type paramType, Annotation[] paramArrayOfAnnotation,
MediaType mt,
MultivaluedMap<String, Object> paramMultivaluedMap,
OutputStream entityStream) //NOPMD
throws IOException, WebApplicationException
{
dto.setDescription("text Description");
// CONTINUE THE DEFAULT SERIALIZATION PROCESS
}
}
推荐答案
MessageBodyWriter
不需要执行逻辑来操纵实体.它的职责只是编组/序列化.
The MessageBodyWriter
shouldn't need to perform an logic to manipulate entities. It's responsibility is simply to marshal/serialize.
您正在寻找的是 WriterIntercptor
的目的是精确执行您要尝试执行的操作,它会在序列化之前操纵该实体.
What you are looking for instead is an WriterIntercptor
, whose purpose is to do exactly what you are trying to do, manipulate the entity before being serialized.
这是一个例子
@Provider
public class MyDTOWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
Object entity = context.getEntity();
if (entity instanceof MyDTO) {
((MyDTO)entity).setDescription("Some Description");
}
context.proceed();
}
}
您可以添加注释,以便仅某些资源方法/类使用此拦截器,例如
You can add annotation so only certain resource methods/classes use this interceptor, e.g.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;
@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AddDescription {
}
...
@AddDescription
@Provider
public class MyDTOWriterInterceptor implements WriterInterceptor {
...
@Path("dto")
public class MyDTOResource {
@GET
@AddDescription
@Produces(MediaType.APPLICATION_JSON)
public Response getDto() {
return Response.ok(new MyDTO()).build();
}
}
如果由于某种原因您不能更改类(也许这就是为什么要在这里设置描述(谁知道)的原因),则可以使用
If for some reason you can't alter the class (maybe that's why you need to set the description here, who's knows), then you can use Dynamic Binding, where you don't need to to use annotations. You can simple do some reflection to check the method or class. The link has an example.
这篇关于泽西岛更新实体属性MessageBodyWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!