MessageBodyWriter 用于 Jersey 中的自定义媒体类型
MessageBodyWriter for custom media type in Jersey
我一直在编写 RESTful Web 服务。我使用的技术:
- Glassfish 3(基于 Java6)
- JDKv7
- Eclipse EE 开普勒
- 泽西岛(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 服务。
我的问题:
- 这是involving/coding自定义媒体类型的正确方法吗?
- 我在服务客户端收到的数据并不完全正确。即,值需要是数字 47 而不是“/”。那么,为什么我得到的是 a 字符而不是数字?
- 正如您在资源方法中所见,我向自定义 POJO 输入了两个值:数字和字符串。在服务客户端,我有
InputStream
。我得到整体数据的字节数组。如何将数据读取为单独数据块,这些数据在我的 POJO 中编码为字段?我可以逐字节读取,但这样做是否正确?
我想出的解决方案很简单。
我只需要为 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。
运行顺利。
我一直在编写 RESTful Web 服务。我使用的技术:
- Glassfish 3(基于 Java6)
- JDKv7
- Eclipse EE 开普勒
- 泽西岛(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 服务。
我的问题:
- 这是involving/coding自定义媒体类型的正确方法吗?
- 我在服务客户端收到的数据并不完全正确。即,值需要是数字 47 而不是“/”。那么,为什么我得到的是 a 字符而不是数字?
- 正如您在资源方法中所见,我向自定义 POJO 输入了两个值:数字和字符串。在服务客户端,我有
InputStream
。我得到整体数据的字节数组。如何将数据读取为单独数据块,这些数据在我的 POJO 中编码为字段?我可以逐字节读取,但这样做是否正确?
我想出的解决方案很简单。
我只需要为 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。
运行顺利。