MessageBodyWriter 用于 Jersey 中的自定义媒体类型

MessageBodyWriter for custom media type in Jersey

我一直在编写 RESTful Web 服务。我使用的技术:

我已经为自定义 MediaType 创建了自定义 POJO:

public final class SimpleEntity{

private int value = 0;
private String stValue = "";

public SimpleEntity(){}

public SimpleEntity(int value, String stValue) {
    super();
    this.value = value;
    this.stValue = stValue;
}
... getters, setters

我的资源方法:

@POST
@Produces("application/entity")
@Path("/getSimpleEntityNeedsProvider")
public Response getSimpleEntityNeedsProvider(){
    SimpleEntity entity = new SimpleEntity(47, "String input value");

    return Response.ok().entity(entity).build();
}

我的消息正文作者:

 @Provider
@Produces("application/entity")
public final class SimpleEntityBodyWriterProvider implements MessageBodyWriter<SimpleEntity>{

    private static Logger log = Logger.getLogger(Class.class);

    @Override
public long getSize(SimpleEntity arg0, Class arg1, Type arg2, Annotation[] arg3,
        MediaType arg4) {

    return -1;
}

@Override
public boolean isWriteable(Class arg0, Type arg1, Annotation[] arg2,
        MediaType arg3) {
    if(arg0.equals(SimpleEntity.class)){            
        return true;
    }
    return false;
}

@Override
public void writeTo(SimpleEntity entity, Class arg1, Type arg2, Annotation[] arg3,
        MediaType media, MultivaluedMap arg5, OutputStream out)
        throws IOException, WebApplicationException {

    log.log(Level.INFO, "Input to SimpleEntityBodyWriterProvider: "+entity.getValue());

    out.write(entity.getValue());   
    out.write(entity.getStValue().getBytes());
}

}

我的服务客户:

private void getSimpleEntityNeedsProvider(String strUrl, String method){
    HttpURLConnection connect = null;
    try {
        URL url = new URL(strUrl);
        connect = (HttpURLConnection)url.openConnection();

        connect.setRequestProperty("Accept", "application/entity");// Accept from server
        connect.setRequestMethod(method);   
        connect.connect();

        InputStream input = connect.getInputStream();

        int size = input.available();
        byte[] b = new byte[size];
        input.read(b, 0, size);

        System.out.println("From resource: "+new String(b));

        System.out.println("Status: "+connect.getResponseCode()+" : "+connect.getResponseMessage());

    }
    catch(IOException e){
        e.printStackTrace();
    }
}

根路径:

    @ApplicationPath("/rest/v6")
public class AppV6 extends Application {
    private static Logger log = Logger.getLogger(Class.class.getName());
    public AppV6(){}

    @Override


public Set<Class<?>> getClasses(){
        Set<Class<?>> cls = new HashSet<>();
    cls.add(SimpleEntity.class);
    cls.add(SimpleEntityBodyWriterProvider.class);

    return cls;
}

}

当我 运行 应用程序时,我从我的服务客户端得到以下输出:

From resource: /String input value
Status: 200 : OK

我想使用自定义媒体类型和 MessageBodyWriter 以便更好地了解 RESTful/Jersey 服务。 我的问题:

我想出的解决方案很简单。 我只需要为 InputStream 使用包装器 class,即

InputStream data = connect.getInputStream();
        DataInputStream input = new DataInputStream(data);

        System.out.println("From resource: "+input.readInt()+" : "+input.readUTF());

需要在 MessageBodyWriter 实现 class 中应用相同的包装器。我添加了 MessageBodyReader 的实现(与上面相同的规则适用)以在资源方法中读取自定义 POJO/MediaType。 运行顺利。