2012-03-07 1 views
5

В настоящее время я работаю над API RESTful. У меня есть класс Employee и класс EmployeeResource. У меня также есть настраиваемый DateAdapter, который меняет свойства Date на Long timestamps. Однако мои ответы JSON показывают временные метки как строки (завернутые в двойные кавычки), а не числа (без двойных кавычек). Вот сокращенный вариант моего кода и захватили ответ JSON ...JAXB или JAX-RS обматывают номера в моих ответах JSON кавычками, превращая их в строки. Почему это поведение по умолчанию и как его исправить?

Пользовательские DateAdapter

public class DateAdapter extends XmlAdapter<Long, Date> { 
    @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 Класс

@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<Employee> employees; 

    public List<Employee> getEmployees() { 
     return employees; 
    } 
    public void setEmployees(List<Employee> 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 от упаковки все номера в кавычки. Может ли кто-нибудь привести меня туда, где я мог бы это настроить?

Заранее благодарен!

EDIT # 1 2012.03.07 Итак, после некоторого исследования, я думаю, что моя проблема связана с настройкой по умолчанию JSONConfiguration.Notation, MAPPED. Похоже, что NATURAL JSONConfiguration.Notation получит меня, что я хочу. Однако я не нашел ясного примера того, как применять это приложение в целом. Я предполагаю, что я укажу это в своем классе ApplicationConfig, который расширяет javax.ws.rs.core.Application.

EDIT # 2 2012.03.10 Итак, после нескольких исследований я решил использовать библиотеку парсеров JSON, Джексон. Кажется, это самое полное решение JSON, использующее только конфигурацию по умолчанию. По умолчанию Даты переводятся на соответствующие временные метки и сериализуются как числа (без кавычек). Единственный недостаток, с которым я столкнулся, заключается в том, что Джексон в настоящее время не поддерживает аннотации JAXB «@XmlID» и «@XmlIDREF». Поскольку у меня есть прямые самореференции в моей модели данных (не показано выше), я создал еще один вопрос для обсуждения. Если кто-то заинтересован click here to follow that thread...

ответ

2

Примечание: Я EclipseLink JAXB (MOXy) свинца и член группы экспертов JAXB 2 (JSR-222).

Реализация JAX-RS, которую вы используете, может быть выполнена с использованием JAXB (JSR-222) с чем-то вроде Jettison для производства JSON. Отстрелить предоставляет API StAX для взаимодействия с JSON, так что API-интерфейсы Stax не имеют никакого рода ввод текста WRT, все простые значения получают лечение в виде строк:

Чтобы получить поведение, которое вы ищете, вы можете использовать другое связующее решение. Мы добавляем эту поддержку в MOXy-компонент для EclipseLink 2.4:

Чтобы настроить Moxy в качестве JSON-связывающего поставщика в среде JAX-RS, вы можете создать 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<Object>, MessageBodyWriter<Object>{ 

    @Context 
    protected Providers providers; 

    public boolean isReadable(Class<?> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType) { 
     return true; 
    } 

    public Object readFrom(Class<Object> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType, 
     MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
     throws IOException, WebApplicationException { 
     try { 
      Unmarshaller u = getJAXBContext(type, mediaType).createUnmarshaller(); 
      u.setProperty("eclipselink.media-type", mediaType.toString()); 
      u.setProperty("eclipselink.json.include-root", false);//tiny fix 
      return u.unmarshal(new StreamSource(entityStream), (Class) genericType); 
     } catch(JAXBException jaxbException) { 
      throw new WebApplicationException(jaxbException); 
     } 
    } 

    public boolean isWriteable(Class<?> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType) { 
     return true; 
    } 

    public void writeTo(Object object, Class<?> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType, 
     MultivaluedMap<String, Object> httpHeaders, 
     OutputStream entityStream) throws IOException, 
     WebApplicationException { 
     try { 
      Marshaller m = getJAXBContext(Customer.class, mediaType).createMarshaller(); 
      m.setProperty("eclipselink.media-type", mediaType.toString()); 
      m.setProperty("eclipselink.json.include-root", false); 
      m.marshal(object, entityStream); 
     } catch(JAXBException jaxbException) { 
      throw new WebApplicationException(jaxbException); 
     } 
    } 

    public long getSize(Object t, Class<?> type, Type genericType, 
     Annotation[] annotations, MediaType mediaType) { 
     return -1; 
    } 

    private JAXBContext getJAXBContext(Class<?> type, MediaType mediaType) 
     throws JAXBException { 
     ContextResolver<JAXBContext> resolver 
      = providers.getContextResolver(JAXBContext.class, mediaType); 
     JAXBContext jaxbContext; 
     if(null == resolver || null == (jaxbContext = resolver.getContext(type))) { 
      return JAXBContext.newInstance(type); 
     } else { 
      return jaxbContext; 
     } 
    } 

} 

Дополнительная информация

+0

Привет Блейз, спасибо за информацию. Я просмотрел ссылки, которые вы предоставили, и использование их в качестве основы в конечном итоге привело к странице, в которой описывались разные значения JSONConfiguration.Notation. Обновление этой записи по умолчанию похоже на то, что мне нужно. Я обновил свой оригинальный вопрос, чтобы отразить это. – hypno7oad

+1

Привет, Блейз, я собираюсь выбрать это как ответ, так как я уверен, что это сработает. Тем не менее, это не работает для нас, так как это слишком много для нашего использования. Нам просто нужен простой способ включить нотацию NATURAL в Джерси, а не стандартную нотацию MAPPING. Тем не менее, я буду создавать новый вопрос, так как пример @Provider, который я нашел для Джерси (путем нажатия на ваши ссылки), похоже, не влияет на мое приложение. Если бы вы могли прокомментировать там, я был бы очень благодарен. благодаря – hypno7oad

 Смежные вопросы

  • Нет связанных вопросов^_^