You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Jersey为String类型调用GSON MessageBodyHandler?

问题:如何让Jersey为String类型调用GSON处理器并正确处理数据?

项目背景

我创建了一个用于测试Jersey + GSON的简单项目,实现了GsonMessageBodyHandler implements MessageBodyReader<Object>, MessageBodyWriter<Object>,并在readFrom和writeTo方法中添加System.out.println语句,用于检查该处理器是否被调用。

处理器核心代码:

@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
    Type jsonType = Collection.class.isAssignableFrom(type) ? genericType : type;
    Object o;
    try (Reader jsonReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) {
        o = gson.fromJson(jsonReader, jsonType);
    }

    System.out.println("GsonMessageBodyHandler.readFrom() -= " + o + " =-");

    return o;
}

@Override
public void writeTo(Object o, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    Type jsonType = Collection.class.isAssignableFrom(type) ? genericType : type;
    try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) {
        gson.toJson(o, jsonType, writer);
    }

    System.out.println("GsonMessageBodyHandler.writeTo() -= " + o + " =-  " + gson.toJson(o, jsonType));
}

资源类实现

编写了一个资源类,包含两个接口:一个使用String类型作为输入和响应,另一个使用自定义对象作为输入和响应。

资源类代码:

@Path("/hello")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class HelloResource {

    @Path("/str")
    @POST
    public Response helloStr(String name) {
        System.out.println("Got hello string request [" + name + "]");

        String msg = "Hello " + name + "!";
        return Response.ok().entity(msg).build();
    }

    @Path("/obj")
    @POST
    public Response helloStr(User user) {
        System.out.println("Got hello object request [" + user + "]");

        Message msg = new Message("Hello " + user.name() + "!");
        return Response.ok().entity(msg).build();
    }
}

前端测试代码

制作了带有简单表单的网页,通过以下JavaScript测试这些接口:

function doIt(isSendString) {
    const name = document.getElementById('name').value;

    const opts = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(isSendString ? name : {name: name})
    }

    fetch('ws/hello/' + (isSendString ? 'str' : 'obj'), opts).then(response => {
        if (response.ok) {
            response.json().then(rs => {
                const msg = isSendString ? rs : rs.message;
                alert('Got: ' + msg);
            }).catch(e => {
                console.log(response, e);
                alert('Error parsing data');
            });
        } else {
            console.log(response);
            alert('Error fetching data');
        }
    });

    return false;
}

测试结果

/str接口(String类型)异常情况

  • 浏览器网络面板显示:请求内容为"Ricardo Almeida",响应内容为Hello "Ricardo Almeida"!,而非预期的"Hello Ricardo Almeida!"或'Hello Ricardo Almeida!'
  • 服务器端仅打印资源类中的日志,未打印GSON处理器的日志,且接收的字符串包含双引号:
Got hello string request ["Ricardo Almeida"]

/obj接口(自定义对象)正常情况

  • 浏览器网络面板显示:请求内容为{"name":"Ricardo Almeida"},响应内容为{"message": "Hello Ricardo Almeida!"}
  • 服务器端打印了预期的三条日志(GSON处理器的readFrom、资源类、GSON处理器的writeTo):
GsonMessageBodyHandler.readFrom() -= User[name=Ricardo Almeida] =-
Got hello object request [User[name=Ricardo Almeida]]
GsonMessageBodyHandler.writeTo() -= Message[message=Hello Ricardo Almeida!] =-  {"message":"Hello Ricardo Almeida!"}

提问

如何让Jersey为String类型调用GSON处理器并正确处理数据?


内容的提问来源于stack exchange,提问作者Ricardo Almeida

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:34:58