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

Glassfish 4.1切换Jackson替代Moxy/Jaxb后抛出MessageBodyWriter缺失异常求助

解决GlassFish 4.1切换Jackson后异常抛出时的MessageBodyWriter缺失问题

我之前在GlassFish 4.1上也碰到过一模一样的坑!切换Jackson替代默认MOXy/JAXB后,异常处理这块确实容易出现找不到text/xml或text/plain类型的MessageBodyWriter的问题,给你几个亲测有效的解决方案:

原因分析

默认情况下,GlassFish的MOXy会负责XML和纯文本类型的序列化处理,但Jackson默认只专注于JSON格式。当系统抛出异常需要返回text/xml或text/plain类型响应时,没有对应的Writer来处理,就会触发MessageBodyProviderNotFoundException。


方案1:添加Jackson的XML支持依赖

给项目引入Jackson的XML数据绑定模块,让Jackson具备处理XML格式的能力,这样它会自动注册对应的MessageBodyWriter。

如果用Maven,添加以下依赖(注意版本尽量和GlassFish自带的Jackson版本匹配,GlassFish 4.1自带的是2.3.x系列):

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.3.3</version>
</dependency>

添加后,Jackson就能同时处理JSON和XML类型的响应,异常返回XML格式时就不会再报错。

方案2:自定义ExceptionMapper手动处理响应

创建一个自定义的异常映射器,接管所有异常的响应生成,手动指定返回的媒体类型并构造响应内容,完全绕开自动序列化的问题。

示例代码:

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class GlobalExceptionMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable exception) {
        // 处理text/plain类型响应
        String errorContent = exception.getMessage() != null ? exception.getMessage() : "服务器内部错误";
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .type(MediaType.TEXT_PLAIN)
                .entity(errorContent)
                .build();

        // 如果需要返回XML,可手动构造XML字符串
        // String xmlContent = String.format("<error><message>%s</message></error>", errorContent);
        // return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
        //         .type(MediaType.TEXT_XML)
        //         .entity(xmlContent)
        //         .build();
    }
}

记得给类加上@Provider注解,让JAX-RS自动发现并使用这个映射器。

方案3:保留MOXy处理XML,仅用Jackson处理JSON

如果你只是想替换JSON的序列化实现,没必要完全移除MOXy。可以在JAX-RS应用配置类中指定Jackson为JSON的专属Provider,让MOXy继续负责XML格式的处理。

示例配置类:

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

@ApplicationPath("/api")
public class ApiApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<>();
        // 注册Jackson的JSON Provider
        classes.add(com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.class);
        // 添加你的资源类
        classes.add(UserResource.class);
        classes.addOrderResource.class;
        return classes;
    }
}

这种方式下,MOXy依然会处理XML类型的MessageBodyWriter,Jackson只处理JSON,完美兼容原有逻辑。


额外注意点

  • 尽量保证Jackson版本与GlassFish 4.1自带版本一致,避免类加载冲突;
  • 如果是手动部署Jackson jar包到服务器,注意不要覆盖服务器自带的相关依赖,可调整类加载优先级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:40:12