2016-08-11 74 views
0

我一直在编写RESTful Web服务。MessageBodyWriter在泽西岛的自定义媒体类型

  • Glassfish的3(基于Java 6)
  • JDK V7
  • Eclipse的EE开普勒
  • 泽西(Glassfish的部分)

我创建:我使用的技术定制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 

我的资源m ethod:

@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 

我想,才能有更好的理解基于REST /泽西服务的使用自定义介质类型和MessageBodyWriter。 我有的问题:

  • 这是涉及/编码自定义媒体类型的正确方法吗?
  • 我在服务客户端收到的数据不完全正确。也就是说,而不是“/”这个值需要是一个数字47.所以,为什么我得到一个字符而不是数字?
  • 正如您在资源方法中看到的,我向定制POJO输入了两个值:数字和字符串。在服务客户端,我有InputStream。我得到整体数据的字节数组。我怎样才能读取数据作为单独的数据块,在我的POJO中编码为字段?我可以逐字节读取,但这是否正确?

回答

0

我想到的解决方案很简单。 我只需要使用包装类InputStream,即

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

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

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