英文:
@EnableWebMvc showing date in array formate
问题
我们之前有两个基于Spring Boot的应用程序。一个是基于Spring Rest API的,另一个是基于Spring MVC的。
由于一些业务原因,我们将这两个应用程序合并在一起,因为上下文是相同的,除了Spring自动在Rest API上进行的java.time.LocalDateTime格式化之外,其他一切都运行正常。
之前,它将LocalDateTime格式化为"2018-08-30T18:13:24",但在合并后,它显示为:
[
2018,
08,
30,
18,
13,
24
]
我发现@EnableWebMVC注解是问题所在,但是在移除该注解后,Web MVC页面无法正常工作。
请问我应该怎么做才能使日期以ISO(字符串)格式显示,并且视图解析器和JSP页面能正常工作?
请帮忙,谢谢。
英文:
We had two application on spring boot. One was spring rest api based & second was spring MVC based.
We have megred both the application due to some business reasons as the context was the same and everything is working fine except java.time.LocalDateTime formatting that does by spring automatically on rest API.
previously it was formatting LocalDateTime as "2018-08-30T18:13:24"
but after merging it is showing as [
2018,
08,
30,
18,
13,
24
],
I have found out @EnableWebMVC annotation is the culprit but after removing that annotation web-mvc pages do not work.
What should I do so that date display in ISO (String) format and view resolver & jsp pages works fine?
Please help thanks.
答案1
得分: 7
以下是翻译好的内容:
每个人都在说@EnableWebMvc是罪魁祸首。
但是,没有人说在WebMvc下如何解决这个问题。
所以,为了回答这个问题,是的,有一种方法可以通过不移除@EnableWebMvc来解决这个问题。
在进入答案之前,让我们了解一些概念:
- HttpMessageConverters -> 这些是将Java对象从JSON/XML转换的对象。
- 默认情况下,Spring Boot会添加以下转换器:
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- ResourceHttpMessageConverter
- SourceHttpMessageConverter
- FormHttpMessageConverter
- Jaxb2RootElementHttpMessageConverter
- MappingJackson2XmlHttpMessageConverter
- MappingJackson2HttpMessageConverter
- 所以,每当我们将Java对象转换为JSON时,Spring会按顺序遍历这个转换器列表,并选择相关的转换器进行转换。
- 现在,如果我们将我们自定义的MappingJackson2HttpMessageConverter添加到这个列表中作为最后一个元素,那么Spring就不会使用它,因为在达到我们的转换器(第9个元素)之前,列表的第7个索引处有默认的转换器。
- 因此,为了解决这个问题,我们需要移除默认的MappingJackson2HttpMessageConverter,并添加我们自己的自定义转换器。
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 移除默认的MappingJackson2HttpMessageConverter
converters.removeIf(converter -> {
String converterName = converter.getClass().getSimpleName();
return converterName.equals("MappingJackson2HttpMessageConverter");
});
// 添加您的自定义MappingJackson2HttpMessageConverter
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
converter.setObjectMapper(objectMapper);
converters.add(converter);
WebMvcConfigurer.super.extendMessageConverters(converters);
}
}
注意: 请不要使用WebMvcConfigurer中的configureMessageConverters()方法代替extendMessageConverters(),因为configure方法会移除所有默认安装的转换器。
希望这对像我一样在调试这个问题上浪费了一些时间的人有所帮助
英文:
Everyone is saying @EnableWebMvc is the culprit.
But, no one is saying with WebMvc how to resolve this issue.
So, to answer the question, yes, there is a way to resolve this issue by not removing the @EnableWebMvc.
Before moving into the answer, let's understand a few concepts:
- HttpMessageConverters -> These are the ones that convert Java Objects from and to JSON/XML
- By default, Spring boot will add the following converters:
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- ResourceHttpMessageConverter
- SourceHttpMessageConverter
- FormHttpMessageConverter
- Jaxb2RootElementHttpMessageConverter
- MappingJackson2XmlHttpMessageConverter
- MappingJackson2HttpMessageConverter
- So, whenever we are converting the java object into JSON, then spring will go through this list of converters one by one in order and picks the relevant one to convert
- Now, if we add our custom MappingJackson2HttpMessageConverter to this list as the last element, then spring will not come to it because before reaching our converter(9th element), there is the default converter at the 7th index
- So, to resolve this issue, we need to remove the default MappingJackson2HttpMessageConverte and need to add our custom converter
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// Remove the default MappingJackson2HttpMessageConverter
converters.removeIf(converter -> {
String converterName = converter.getClass().getSimpleName();
return converterName.equals("MappingJackson2HttpMessageConverter");
});
// Add your custom MappingJackson2HttpMessageConverter
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
converter.setObjectMapper(objectMapper);
converters.add(converter);
WebMvcConfigurer.super.extendMessageConverters(converters);
}
}
Note: Please don't use configureMessageConverters() instead of extendMessageConverters() from WebMvcConfigurer because configure method will remove all the existing converters which will be installed by default.
Hope it will help someone like me who has wasted some hours debugging the issue
答案2
得分: 0
如果您正在使用 **Jackson** 作为您的 JSON <-> POJO 映射器,您可以设置以下属性:
```yml
spring:
jackson:
date-format: yyyy-MM-dd'T'hh:mm:ss
serialization:
write-dates-as-timestamps: false
spring.jackson.serialization.write-dates-as-timestamps
的默认值为 true
,它将 LocalDateTime
序列化为数组,就像您展示的那样。
如果需要更精细的控制,您还可以像下面这样对日期时间字段进行注释:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss")
private LocalDateTime datetime;
它将优先于上述属性。
在这里查看其他与 JSON 相关的 Spring Boot 属性:https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#json-properties
<details>
<summary>英文:</summary>
If you are using **Jackson** as your JSON <-> POJO mapper, you can set the following properties:
```yml
spring:
jackson:
date-format: yyyy-MM-dd'T'hh:mm:ss
serialization:
write-dates-as-timestamps: false
spring.jackson.serialization.write-dates-as-timestamps
defaults to true
, which serializes LocalDateTime
as an array, like the one you show.
For a finer-grained control, you can also annotate date-time fields like following:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss")
private LocalDateTime datetime;
It takes precedence over the above property.
Take a look at other JSON related Spring Boot properties here: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#json-properties
答案3
得分: 0
对于那些仍然面临这个问题的人,@EnableWebMVC
明显是问题的根源,因为它禁用了 Web MVC 自动配置的默认行为,取而代之的是你自己的配置。
关于这一点,Spring Boot 参考文档提到:
> Spring MVC 自动配置
...
如果你想完全控制 Spring MVC,可以添加一个带有 @EnableWebMvc
注解的 @Configuration...
然而,你可以在不丢失默认自动配置行为的情况下添加自定义配置。
> 如果你想要保留那些 Spring Boot MVC 自定义,并且进行更多的 MVC 自定义(拦截器、格式化器、视图控制器和其他特性),你可以添加一个类型为 WebMvcConfigurer 的自己的 @Configuration 类,但是不要加上 @EnableWebMvc
。
也就是说,移除 @EnableWebMVC 应该能够正常运行。
英文:
For those still facing the issue, @EnableWebMVC
is definitely the culprit as it disables the Web MVC auto-configuration default behaviors in favor of yours.
About that, the Spring Boot reference documentation says:
> Spring MVC Auto-configuration
...
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc
...
However, you can add custom configuration without losing the default auto-configuration behaviors.
>If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc
.
That said, removing @EnableWebMVC should work just fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论