RESTful Web服务返回JSON时触发NullPointerException问题排查
排查GlassFish中REST服务返回JSON时的NullPointerException问题
我来帮你一步步分析并解决这个空指针异常问题:
问题场景回顾
你正在搭建一个基础REST服务,期望传入String类型的id参数后返回对应的User JSON对象,但访问http://localhost:8080/RESTfulServiceLIT_war_exploded/users/{id}时,GlassFish日志抛出了NullPointerException,异常指向MOXyJsonProvider.writeTo方法。
异常原因分析
结合日志和你的代码,这个NPE主要有两个核心触发点:
- 返回null对象给序列化器:当传入的
id不在UserDAO的userMap中时,UserDAO.getUser(id)会返回null,而GlassFish默认的MOXy序列化器在尝试序列化null对象时会直接抛出空指针异常。 - User类不符合JAXB序列化规范:MOXy作为JAXB的实现,要求被序列化的类必须具备公共无参构造器,且属性要有对应的getter方法(建议添加setter),否则序列化过程中也会出现异常。
另外还要注意:如果你访问的URL里直接保留了占位符{id}(没有替换成实际存在的id值,比如K1、S1),那传入的id字符串就是"{id}",这个值不在预初始化的userMap中,必然返回null触发异常。
解决方案
1. 处理id不存在的情况,避免返回null
修改Main类中的getUser方法,当查询不到用户时抛出WebApplicationException返回404状态码,既符合REST规范,又从根源避免了序列化null对象的问题:
@GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Path("/{id}") public User getUser(@PathParam("id") String id) { User user = UserDAO.getUser(id); // 用户不存在时返回404错误 if (user == null) { throw new WebApplicationException(Response.Status.NOT_FOUND); } return user; }
2. 确保User类满足序列化要求
MOXy需要你的User类具备以下条件才能正常完成序列化:
- 公共的无参构造器
- 所有属性的getter方法(setter可选,但建议添加以保证兼容性)
- 添加
@XmlRootElement注解明确JAXB根元素
示例User类代码:
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User { private String id; private String name; private String role; // 必须的无参构造器 public User() {} // 带参数的构造器 public User(String id, String name, String role) { this.id = id; this.name = name; this.role = role; } // 所有属性的getter和setter方法 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } }
3. 验证请求URL的正确性
确保你访问的是实际存在的id,比如:http://localhost:8080/RESTfulServiceLIT_war_exploded/users/K1
而不是带着占位符{id}的无效URL。
验证修改
完成以上调整后重新部署服务:
- 访问存在的id,会正常返回User的JSON数据
- 访问不存在的id,会返回404状态码,不再抛出空指针异常
内容的提问来源于stack exchange,提问作者Shox2711
相关产品推荐
相关产品推荐

