【发布时间】:2017-03-23 13:25:11
【问题描述】:
我有一个运行 Spring MVC 3.1.x 的 Java 1.7 应用程序,具有休眠功能,由 SQL Server 2008 支持,使用 Jackson 1.9.x 将域对象序列化为 JSON。
项目结构只是一个标准的 Spring MVC 设置,没什么特别的,我有一个控制器、服务和存储库使用休眠连接到 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);
}
}
然后我用类注释了我的域类getter:
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
}
]
我还查看了有关堆栈溢出和其他 Web 资源的各种不同答案,这些答案大多只是将我指向上面的代码。这里的任何帮助都会很棒,谢谢。
更新
我后来发现了一些用于 jackson ObjectMapper 和 MappingJacksonHttpMessageConverter 的 bean 配置,它们可能会覆盖我的类注释?
请记住,我正在使用遗留代码,因此请不要在这里判断任何已弃用的用法。这是配置sn-p:
<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>
更新:
bean 配置是关键。我只需要向对象映射器添加日期格式,并且在应用程序中使用全局。我会用全套豆子添加一个正确的答案。我还刚刚删除了所有域类级别注释的序列化程序,因为它们由于应用程序级别的 bean 而被忽略。
【问题讨论】:
-
您能否向我们展示您希望将对象序列化为 JSON(您的控制器)的位置以及您看到的实际 JSON?
-
我无法重现这个。请提供minimal reproducible example。
-
@Sotirios Delimanolis 这是否意味着您无法通过使用域对象代码和序列化程序与具有上述类似依赖关系的标准 spring mvc 3.1 应用程序来重现该问题,或者您的意思是没有这里有足够的细节来做到这一点吗?我不想通过包含整个应用程序使问题变得过于嘈杂。你能不能假设应用程序正常工作而只专注于序列化程序方面?
-
我无法重现意味着我采用了您在此处发布的代码,对您的配置做出了最小的假设,并尝试执行它。我得到了结果
[{"dateTimeOfEvent":"Nov 9, 2016 9:33:31 AM"}],这不是你描述的。我不希望你发布你的整个申请。我希望您调试您的应用程序,直到您可以删除所有对问题没有影响的部分,然后发布minimal reproducible example。 -
有趣的是,您得到了描述“2016 年 11 月 9 日上午 9:33:31”的日期格式,因为我在示例中的格式字符串应输出“2016-11-09 09:33” :31 {您的时区}”。您是否调试过您的代码以查看它是否确实命中了 JsonSerializer?还是您刚刚获得了不同的简单日期格式?
标签: java json spring-mvc jackson