从Wildfly迁移至TomEE时Jackson JsonProperty注解失效问题排查
TomEE中Jackson @JsonProperty注解别名不生效的问题解决
问题场景
有如下标注Jackson注解的ResponseMsg实体类:
public class ResponseMsg implements Serializable{ public ResponseMsg(String ret, String msg){ this.returnCode = ret; this.errorMsg = msg; } @JsonProperty("ret") private int returnCode; @JsonProperty("msg") private String errorMessage; // .... getters and setters }
对应的JAX-RS REST接口代码(已修正原代码的语法错误):
@Path("/test") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class ProcessMessageResource { @POST @Path("/proc") public Response process() { ResponseMsg er = new ResponseMsg("abc","some message"); return Response.ok(er).build(); } }
该代码在Wildfly 26中运行正常,返回的JSON会使用@JsonProperty指定的别名:
{ "ret": "abc", "msg": "some message" }
但迁移至基于Jakarta EE 9.1的TomEE后,返回的JSON未识别注解别名,直接输出原属性名:
{ "returnCode": "abc", "errorMessage": "some message" }
原因分析
TomEE默认采用Apache Johnzon作为JSON序列化/反序列化的实现,而Johnzon并不兼容Jackson的@JsonProperty注解,因此会直接按照实体类的原始属性名生成JSON。
解决方法
要让Jackson注解生效,需要将TomEE的JSON提供者替换为Jackson,具体步骤如下:
1. 添加Jackson Jakarta EE依赖
在项目的pom.xml中引入兼容Jakarta EE 9.1的Jackson JAX-RS提供者依赖:
<dependency> <groupId>com.fasterxml.jackson.jakarta.rs</groupId> <artifactId>jackson-jakarta-rs-json-provider</artifactId> <version>2.15.2</version> <!-- 选择与Jakarta EE 9.1匹配的版本 --> </dependency>
2. 配置TomEE优先使用Jackson
有两种配置方式可选:
方式一:通过beans.xml指定替代实现
在WEB-INF/beans.xml中添加如下配置,将Jackson的JSON提供者设为优先选择:<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd" version="3.0" bean-discovery-mode="annotated"> <alternatives> <class>com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider</class> </alternatives> </beans>方式二:在Application子类中注册Jackson提供者
创建JAX-RS的Application子类,手动注册Jackson提供者和你的资源类:@ApplicationPath("/api") public class RestApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); classes.add(ProcessMessageResource.class); classes.add(JacksonJsonProvider.class); return classes; } }
3. 验证结果
重新部署项目后调用接口,即可得到使用@JsonProperty指定别名的JSON响应。
内容的提问来源于stack exchange,提问作者ps0604
相关产品推荐
相关产品推荐

