来自纯字符串的 Wildfly RestEASY return json

Wildfly RestEASY return json from plain string

我有 angular 应用程序,我想为用户必须登录但应该能够从他离开页面的地方恢复的情况创建一个小型会话存储。

存储部分非常简单,因为我按原样存储了收到的 json 字符串。但是当我重新调整值时,字符串被转义为字符串而不是 json。有没有办法 return 一个字符串(已经是 json)作为 json 对象?

@Path("/session")
public class SessionStore extends Application {
    @POST
    @Path("/save/{variable}")
    @Consumes("application/json")
    public boolean save(@PathParam("variable") String var, String json) throws Exception {
        getSession().setAttribute(var, json);
        return true;
    }

    @GET
    @Path("/load/{variable}")
    @Produces("application/json")
    public Object load(@PathParam("variable") String var) {
        return getSession().getAttribute(var); // this string is already a json
    }
}

如果您不希望 return 值自动装箱为 json 格式,请告诉您的 JAX-RS 实现为 return 纯文本而不是 json 与 @Produces("text/plain").

@GET
@Path("/load/{variable}")
@Produces("text/plain")
public String load(@PathParam("variable") String var) {
    //the cast may not be necessary, but this way your intention is clearer
    return (String) getSession().getAttribute(var);
}

我不知道您使用的是哪个 JSON 序列化程序。我无法用 Jackson 重现这种行为。

起初我会将您的方法的 return 时间更改为字符串。因为将 String 转换为 JSON-String 是没有意义的,除非它已经是 JSON-String,因此您的 JSON 序列化程序不应触及它。如果它试图变得更聪明,您可以为字符串注册自定义 MessageBodyWriter

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JsonStringSerializer implements MessageBodyWriter<String> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type == String.class;
    }

    @Override
    public long getSize(String t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(String entity, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        entityStream.write(entity.getBytes(Charset.forName("UTF-8")));      
    }

}

我强烈建议不要将 @Produces 注释 更改为 text/plain。这可能会导致 return 生成正确的内容,但也会将 Content-Type header 更改为 text/plain。所以你发送 JSON 但告诉你的客户它不是 JSON。如果客户相信你,他就不会再解析内容了。