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

时间:2016-08-11 15:13:55

标签: rest jersey glassfish java-ee-6 provider

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

  • Glassfish 3(基于Java 6)
  • JDK v7
  • Eclipse EE Kepler
  • 泽西岛(Glassfish的一部分)

我为自定义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服务。 我有的问题:

  • 这是涉及/编码自定义媒体类型的正确方法吗?
  • 我在服务客户端收到的数据并不完全正确。即,而不是&#34; /&#34;值必须是一个数字47.那么,为什么我得到一个字符而不是数字?
  • 正如您在资源方法中看到的,我将两个值输入到自定义POJO:digit和string。在服务客户端,我有InputStream。我得到整数数据的字节数组。如何将数据读取为单独数据的块,这些数据在我的POJO中被编码为字段?我可以逐字节读取,但这是一种正确的方法吗?

1 个答案:

答案 0 :(得分:0)

我发现,解决方案很简单。 我只需要为InputStream使用包装类,即

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

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

需要在MessageBodyWriter实现类中应用相同的包装器。我添加了MessageBodyReader的实现(与上面相同的规则),用于在资源方法中读取自定义POJO / MediaType。 它运作顺畅。