2016-11-09 3 views
-2

У меня есть приложение Java 1.7 Spring MVC 3.1.x, с спящим режимом, поддерживаемое SQL Server 2008, с использованием Jackson 1.9.x для сериализации объектов домена в JSON.Java Spring MVC аннотированная пользовательская дата json serializer игнорируется

Структура проекта - это стандартная установка Spring MVC, ничего особенного, у меня есть контроллер, служба и репозиторий, подключенные с помощью hibernate к SQL Server. О, и я использую Maven 3.3.9 для управления зависимостями.

Моя проблема заключается в том, что поле даты не отформатировано правильно. Данные, возвращаемые с моей конечной точки, просто имеют формат по умолчанию для номера эпохи.

Так справиться с этим я создал пользовательский сериалайзер:

import org.codehaus.jackson.JsonGenerator; 
import org.codehaus.jackson.JsonProcessingException; 
import org.codehaus.jackson.map.JsonSerializer; 
import org.codehaus.jackson.map.SerializerProvider; 

import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

public class JsonDateSerialiser extends JsonSerializer<Date> { 

    @Override 
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { 
     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
     String formattedDate = simpleDateFormat.format(date); 
     jsonGenerator.writeString(formattedDate); 
    } 
} 

Тогда я аннотированный мой домен класса поглотитель с классом:

import my.package.JsonDateSerialiser; 
import org.codehaus.jackson.map.annotate.JsonSerialize; 
import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 
import java.util.Date; 

@Entity() 
@Table(name = "tableName") 
@XmlRootElement 
@XmlAccessorType(value = XmlAccessType.PROPERTY) 
public class MyDomainObject { 

    @Id 
    @Temporal(TemporalType.DATE) 
    private Date dateTimeOfEvent; 

    @JsonSerialize(using = JsonDateSerialiser.class) 
    public Date getDateTimeOfEvent() { 
     return dateTimeOfEvent; 
    } 

    public void setDateTimeOfEvent(Date dateTimeOfEvent) { 
     this.dateTimeOfEvent = dateTimeOfEvent; 
    } 
} 

Но аннотацию игнорируется.

Вот мой контроллер раздели обратно (импорт минус):

@Controller 
@RequestMapping(value = "/some/data") 
public class MyDataController { 

    @Autowired 
    private MyDataService myDataService; 

    @RequestMapping(
     method = RequestMethod.GET, 
     value = "/{eventType}", 
     produces = MediaType.APPLICATION_JSON_VALUE 
) 
    public @ResponseBody List<MyDomainObject> getDataForEventType(@PathVariable("eventType") String eventType){ 
     return myDataService.getDataForEventType(eventType); 
    } 

} 

Я пытался поставить его на поле не радость. Я пробовал аннотировать пользовательский сериализатор с @Entity, который ничего не сделал. При отладке пользовательского сериализатора serialize метод не попадает.

Я получаю данные JSON от службы, но у нее просто есть номер для даты.

Пример JSON вернулся:

[ 
{ 
    "dateTimeOfEvent": 1478701160000 
}, 
{ 
    "dateTimeOfEvent": 1478701515000 
} 
] 

Я также посмотрел на различные разные ответы на переполнение стека и других веб-ресурсов, которые в основном только указал мне обратно в код, который я выше. Спасибо за помощь, спасибо.

UPDATE

С тех пор я обнаружил некоторые конфигурации боба для Джексона ObjectMapper и MappingJacksonHttpMessageConverter, которые могли бы быть переопределение моего класса аннотаций могут быть?

Имейте в виду, что я работаю с устаревшим кодом, поэтому не судите о любом устаревающем использовании здесь, пожалуйста. Вот конфиг фрагмент:

<bean id="jaxbAnnIntrospector" class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" /> 
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"> 
    <property name="serializationConfig.annotationIntrospector" ref="jaxbAnnIntrospector" /> 
    <property name="deserializationConfig.annotationIntrospector" ref="jaxbAnnIntrospector" /> 
</bean> 

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" 
       p:objectMapper-ref="jacksonObjectMapper" /> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

UPDATE:

Компонент конфигурации был ключ. Мне просто нужно было добавить формат даты в mapperper объекта, который использовался глобально в приложении. Я добавлю правильный ответ с полным набором бобов. Я также удалил все аннотированные сериализаторы уровня класса домена, поскольку они были проигнорированы из-за компонентов уровня приложения.

+0

Можете ли вы показать нам, где вы ожидаете, что объект сериализации в JSON (ваш контроллер) и фактической JSON вы видите? –

+0

Я не могу воспроизвести это. Пожалуйста, предоставьте [mcve]. –

+0

@Sotirios Delimanolis Означает ли это, что вы не можете воспроизвести проблему, используя объектный код домена и сериализатор со стандартным приложением Spring mvc 3.1 с аналогичными зависимостями, как упомянуто, или вы имеете в виду, что здесь недостаточно деталей для этого? Я не хотел, чтобы вопрос был слишком шумным, включая целое приложение. Не можете ли вы предположить, что приложение работает и просто сосредоточиться на аспекте сериализации? – Jeremy

ответ

0

Таким образом, проблема была просто конфигурацией компонента уровня приложения, которая переопределяла мои аннотации уровня класса.

Это обновленная версия конфигурации боба для картографов Джексона и т.д. Обратите внимание на дополнительных SimpleDateFormat боба и ObjectMapperdateFormat свойство его использование.

<bean id="jsonDateFromat" class="java.text.SimpleDateFormat"> 
    <constructor-arg value="yyyy-MM-dd HH:mm:ss z"/> 
</bean> 
<bean id="jaxbAnnIntrospector" class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" /> 
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"> 
    <property name="serializationConfig.annotationIntrospector" ref="jaxbAnnIntrospector" /> 
    <property name="deserializationConfig.annotationIntrospector" ref="jaxbAnnIntrospector" /> 
    <property name="dateFormat" ref="jsonDateFromat"/> 
</bean> 

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" 
       p:objectMapper-ref="jacksonObjectMapper" /> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

Я удалил все аннотации уровня класса, поскольку они были просто проигнорированы из-за конфигурации этого уровня приложения.

Это было хорошо для меня, поскольку в конце концов была настроена конфигурация уровня приложения, но было бы интересно иметь сценарий, в котором оба были необходимы.

Вот JSON после того, как я сделал это изменение в конфигурации:

[ 
{ 
    "dateTimeOfEvent": "2016-11-09 14:19:20 GMT" 
}, 
{ 
    "dateTimeOfEvent": "2016-11-09 14:25:15 GMT" 
} 
] 
-1

Непросто получить вашу проблему с тем, что вы здесь показываете. Тем не менее, я хочу поделиться с вами своей мыслью. Ваш сериализатор выполнен правильно. Здесь вы используете библиотеку jackson, чтобы вы просто выполняли сериализацию, сериализовывая json-строку для java-объекта. Наверное, вы можете решить проблему на этом этапе.Сделать сериализации вы можете сделать это Liks:

ObjectMapper mapper = new ObjectMapper(); 
//deserialize json to object 
MyDomainObject domainObject = mapper.readValue("Your json file or json string", MyDomainObject.class); 

//serialize object to json string 
String jsonString = mapper.mapper.writeValueAsString(domainObject); 

и дату и другие поля будут упорядочены правильно

Я нашел учебник Jackson Json Annotation Example, что также создает пользовательские даты сериалайзер.

+0

Я не понимаю цели этого ответа. Если вы не можете воспроизвести проблему, отметьте/проголосовать, чтобы закрыть вопрос по этой причине. Они не пытаются десериализовать JSON, они пытаются сериализовать POJO _to_ JSON. –

+0

@SotiriosDelimanolis. У меня проблема, и я хочу показать как десериализацию, так и сериализацию здесь. Возможно, я допустил ошибку ввода. –

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