Java MessageBodyWriter的结果未发送到浏览器

Java MessageBodyWriter的结果未发送到浏览器,java,json,rest,jersey,Java,Json,Rest,Jersey,这是我的资源类: @Component @Path("forum/categories") @Produces(MediaType.APPLICATION_JSON) public class ForumCategoryResource { @Context UriInfo uriInfo; @Resource(name="forumService") private ForumService forumService; @GET @Path(&qu

这是我的资源类:

@Component
@Path("forum/categories")
@Produces(MediaType.APPLICATION_JSON)
public class ForumCategoryResource {

@Context
UriInfo uriInfo;

@Resource(name="forumService")
private ForumService forumService;

@GET
@Path("tree/{rootId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getCategoryTreeById(@PathParam("rootId") Integer rootId) {
    
    System.out.println("Got request for tree by id: " + rootId);
    
    Tree<ForumCategory> tree = forumService.getCategoryTreeById(rootId);
    
    return Response.ok(new GenericEntity<Tree<ForumCategory>>(
            tree, tree.getClass()
    )).build(); 
}
这是我的树类MessageBodyWriter:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class TreeWriter implements MessageBodyWriter<Tree<?>> {
    
    private static final Tree<?> NULL_TREE = new Tree<Object>((Object)null);
    private static final Charset CHARSET = Charset.forName("UTF-8");
    
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        System.out.println("isWritable");
        return type == NULL_TREE.getClass();
    }

    @Override
    public long getSize(Tree<?> tree, Class<?> type, Type genericType,
        Annotation[] annotations, MediaType mediaType) {
        System.out.println("getSize");
    
        try {
            return getTreeAsJsonString(tree).length() * Character.SIZE / Byte.SIZE;
        } 
        catch (IOException e) {
            throw new WebApplicationException(e);
        }
    }

    @Override
    public void writeTo(Tree<?> tree, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {

        System.out.println("writeTo");
        System.out.println(tree);
        String jsonString = getTreeAsJsonString(tree);
        System.out.println(jsonString);
        entityStream.write(jsonString.getBytes(CHARSET));
        entityStream.flush();
    }
    
    private String getTreeAsJsonString(Tree<?> tree) throws IOException {
        
        if (tree != null) {
            
            StringBuilder result = new StringBuilder();
            appendTree(result, tree);
            return result.toString();
        }
        
        return "null";
    }

    private void appendTree(StringBuilder result, Tree<?> tree) throws IOException {
        
        result.append("{");     
        appendTreeValue(result, tree);
        result.append(",");
        appendTreeChildren(result, tree);
        result.append(",");
        appendTreeHeight(result, tree);
        result.append("}");
        
    }

    private void appendTreeHeight(StringBuilder result, Tree<?> tree) {
        result.append("\"height\":");
        result.append(tree.getHeight());
    }

    private void appendTreeChildren(StringBuilder result, Tree<?> tree) throws IOException {
        
        result.append("\"children\":[");
        
        boolean hasChildren = false;
        
        for (Tree<?> child : tree.getChildren()) {
            appendTree(result, child);
            result.append(",");
            hasChildren = true;
        }
        
        if (hasChildren) {
            result.deleteCharAt(result.length() - 1);
        }

        result.append("]");
    }

    private void appendTreeValue(StringBuilder result, Tree<?> tree) throws IOException {
        result.append("\"value\":");
        result.append(objectMapper.writeValueAsString(tree.getValue()));        
    }
}
问题是我的浏览器中没有显示任何内容。从普通POJO接收json就像一个符咒。我唯一的问题是从返回树数据的rest服务中得到答案

编辑:

我尝试使用POSTMAN rest客户端,但失败,出现以下消息:

响应状态为0。 查看W3C XMLHttpRequest 2级规范,了解有关何时发生这种情况的更多详细信息

W3C规范规定:

status属性必须返回运行以下步骤的结果:

如果状态为未发送或已打开,则返回0并终止这些步骤

如果设置了错误标志,则返回0并终止这些步骤

返回HTTP状态代码

我想出来了

首先,我尝试从getSize返回0

然后我可能使用string.length()*Character.SIZE/Byte.SIZE错误计算了长度


然后我尝试从getSize返回-1,这使得jersey json可以自己计算长度。

我确实得到一些HTTP头:HTTP/1.1 200 OK Content length:400 Content Type:application/json Server:Jetty(6.1.10)
public class ForumCategory {

    private Integer forumCategoryId;
    private String nameKey;
    private String descriptionKey;
    
    public ForumCategory() {
    }
    
    public ForumCategory(String nameKey, String descriptionKey) {
        this.nameKey = nameKey;
        this.descriptionKey = descriptionKey;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(forumCategoryId).toHashCode();
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }
        
        if (getClass() != obj.getClass()) {
            return false;
        }

        ForumCategory other = (ForumCategory) obj;
        return new EqualsBuilder().append(this.forumCategoryId, other.forumCategoryId).isEquals();
    }

    public String getNameKey() {
        return nameKey;
    }

    public void setNameKey(String nameKey) {
        this.nameKey = nameKey;
    }

    public String getDescriptionKey() {
        return descriptionKey;
    }

    public void setDescriptionKey(String descriptionKey) {
        this.descriptionKey = descriptionKey;
    }

    public Integer getForumCategoryId() {
        return forumCategoryId;
    }

    public void setForumCategoryId(Integer forumCategoryId) {
        this.forumCategoryId = forumCategoryId;
    }

    @Override
    public String toString() {
        return "ForumCategory [forumCategoryId=" + forumCategoryId
                + ", nameKey=" + nameKey + ", descriptionKey=" + descriptionKey
                + "]";
    }
    
    
}
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class TreeWriter implements MessageBodyWriter<Tree<?>> {
    
    private static final Tree<?> NULL_TREE = new Tree<Object>((Object)null);
    private static final Charset CHARSET = Charset.forName("UTF-8");
    
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {

        System.out.println("isWritable");
        return type == NULL_TREE.getClass();
    }

    @Override
    public long getSize(Tree<?> tree, Class<?> type, Type genericType,
        Annotation[] annotations, MediaType mediaType) {
        System.out.println("getSize");
    
        try {
            return getTreeAsJsonString(tree).length() * Character.SIZE / Byte.SIZE;
        } 
        catch (IOException e) {
            throw new WebApplicationException(e);
        }
    }

    @Override
    public void writeTo(Tree<?> tree, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {

        System.out.println("writeTo");
        System.out.println(tree);
        String jsonString = getTreeAsJsonString(tree);
        System.out.println(jsonString);
        entityStream.write(jsonString.getBytes(CHARSET));
        entityStream.flush();
    }
    
    private String getTreeAsJsonString(Tree<?> tree) throws IOException {
        
        if (tree != null) {
            
            StringBuilder result = new StringBuilder();
            appendTree(result, tree);
            return result.toString();
        }
        
        return "null";
    }

    private void appendTree(StringBuilder result, Tree<?> tree) throws IOException {
        
        result.append("{");     
        appendTreeValue(result, tree);
        result.append(",");
        appendTreeChildren(result, tree);
        result.append(",");
        appendTreeHeight(result, tree);
        result.append("}");
        
    }

    private void appendTreeHeight(StringBuilder result, Tree<?> tree) {
        result.append("\"height\":");
        result.append(tree.getHeight());
    }

    private void appendTreeChildren(StringBuilder result, Tree<?> tree) throws IOException {
        
        result.append("\"children\":[");
        
        boolean hasChildren = false;
        
        for (Tree<?> child : tree.getChildren()) {
            appendTree(result, child);
            result.append(",");
            hasChildren = true;
        }
        
        if (hasChildren) {
            result.deleteCharAt(result.length() - 1);
        }

        result.append("]");
    }

    private void appendTreeValue(StringBuilder result, Tree<?> tree) throws IOException {
        result.append("\"value\":");
        result.append(objectMapper.writeValueAsString(tree.getValue()));        
    }
}
Got request for tree by id: 1
isWritable
getSize
writeTo
ForumCategory [forumCategoryId=1, nameKey=cat.name.a, descriptionKey=cat.desc.a]:2
|- ForumCategory [forumCategoryId=2, nameKey=a, descriptionKey=b]:1

{"value":{"forumCategoryId":1,"nameKey":"cat.name.a","descriptionKey":"cat.desc.a"},"children":[{"value":{"forumCategoryId":2,"nameKey":"a","descriptionKey":"b"},"children":[],"height":1}],"height":2}