JAXB或JAX-RS在我的JSON响应中用引号包装数字,将它们转换为字符串。 为什么这是默认行为,以及如何解决它?
我目前正在开发RESTful API。 我有一个Employee类和一个EmployeeResource类。 我还有一个自定义DateAdapter,它将我的Date属性更改为Long timestamps。 但是,我的JSON响应将时间戳显示为字符串(用双引号括起来)而不是数字(不带双引号)。 这是我的代码的缩写版本和捕获的JSON响应…
自定义DateAdapter
public class DateAdapter extends XmlAdapter { @Override public Date unmarshal(Long v) throws Exception { return new Date(Long.valueOf(v)); } @Override public Long marshal(Date v) throws Exception { return v.getTime(); } }
实体类
@Entity @javax.xml.bind.annotation.XmlRootElement @XmlType(propOrder={"createdOn","empId"}) public class Employee implements Serializable { private Date createdOn; private Integer empId; @Column(nullable=false) @Temporal(TemporalType.TIMESTAMP) @XmlJavaTypeAdapter(DateAdapter.class) public Date getCreatedOn() { return createdOn; } public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; } @Id @XmlID public Integer getEmpId() { return empId; } public void setEmpId(Integer empId) { this.empId = empId; } }
EmployeeResource
@Path("/Employees") @javax.xml.bind.annotation.XmlRootElement @XmlType(propOrder={"hateoas","employees"}) public class EmployeeResource { List employees; public List getEmployees() { return employees; } public void setEmployees(List employees) { this.employees = employees; } @GET @Path("/{id}") @Produces("application/json") public Response getEmployee(@Context UriInfo ui, @PathParam("id") Integer id) { Session session = HibernateUtil.getSession(); session.beginTransaction(); Criteria criteria=session.createCriteria(Employee.class); criteria.add(Restrictions.eq("empId", new Integer(10150))); this.employees = criteria.list(); return Response.ok(this).build(); } }
当前的JSON响应
{ "employees":{ "createdOn":"1330915130163", "empId":"10150" } }
预期的JSON响应
{ "employees":{ "createdOn":1330915130163, "empId":10150 } }
我假设有一些方法可以阻止JAXB或JAX-RS将所有数字包装在引号中。 有人可以指导我到我可以配置的地方吗?
提前致谢!
编辑#1 2012.03.07好的,经过一些研究,我认为我的问题是使用默认的JSONConfiguration.Notation,MAPPED。 看起来像NATURAL JSONConfiguration.Notation会得到我想要的东西。 但是,我还没有找到如何应用该应用程序的明确示例。 我假设我会在扩展javax.ws.rs.core.Application的ApplicationConfig类中指定它。
编辑#2 2012.03.10好的,经过一些研究,我决定使用JSON解析器库,jackson。 它似乎是使用默认配置的最完整的JSON解决方案。 默认情况下,日期会转换为相应的时间戳并序列化为数字(无引号)。 我遇到的唯一缺点是Jackson目前不支持JAXB注释,“@ XmlID”和“@XmlIDREF”。 由于我在我的数据模型中有直接的自引用(上面没有显示),我创建了另一个要讨论的问题。 如果有兴趣点击此处关注该主题…
注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB 2(JSR-222)专家组的成员。
您正在使用的JAX-RS实现可能正在使用类似Jettison的JAXB(JSR-222)实现来生成JSON。 Jettison提供了一个与JSON交互的StAX API,因为StAX API没有任何类型的WRT文本输入,所有简单的值都被视为字符串:
要获得您正在寻找的行为,您可以使用不同的绑定解决方案。 我们将此支持添加到EclipseLink 2.4的MOXy组件中:
要在JAX-RS环境中将MOXy配置为JSON绑定提供程序,可以创建一个MessageBodyReader
/ MessageBodyWriter
,如下所示:
import java.io.*; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import javax.xml.transform.stream.StreamSource; import javax.ws.rs.*; import javax.ws.rs.core.*; import javax.ws.rs.ext.*; import javax.xml.bind.*; @Provider @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class MOXyJSONProvider implements MessageBodyReader
了解更多信息