Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the error of Feign date format conversion

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to solve Feign date format conversion errors". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to solve Feign date format conversion errors.

The scene that appears

The server writes an external interface through springmvc and returns a json string, where the json has a date and the format is yyyy-MM-dd HH:mm:ss.

The client calls the http interface through feign, specifying that the field whose return value is a date in a Dto,Dto is of Date type.

The client calls the interface and throws an exception.

The error exception is as follows

Feign.codec.DecodeException: JSON parse error: Can not deserialize value of type java.util.Date from String "2018-03-07 16:18:35": not a valid representation (error: Failed to parse Date value '2018-03-07 16 purge 18mov 35Z: Can not parse date "2018-03-07 16pura 18lav 35Z": while it seems to fit format' yyyy-MM-dd'T'HH:mm:ss.SSS'Z'', parsing fails (leniency? (null); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.util.Date from String "2018-03-07 16:18:35": not a valid representation (error: Failed to parse Date value '2018-03-07 16 purge 18mov 35Z: Can not parse date "2018-03-07 16pura 18lav 35Z": while it seems to fit format' yyyy-MM-dd'T'HH:mm:ss.SSS'Z'', parsing fails (leniency? Null)) at [Source: java.io.PushbackInputStream@4615bc00; line: 1, column: 696] (through reference chain: com.RestfulDataBean ["data"]-> java.util.ArrayList [0]-> com.entity.XxxDto ["createTime"]) at feign.SynchronousMethodHandler.decode (SynchronousMethodHandler.java:169) at feign.SynchronousMethodHandler.executeAndDecode (SynchronousMethodHandler.java:133) at feign.SynchronousMethodHandler.invoke (SynchronousMethodHandler.java:76) at feign.ReflectiveFeign$FeignInvocationHandler.invoke (ReflectiveFeign.java:103) at com.sun.proxy.$Proxy138.queryMonitorByTime (Unknown Source)

From the exception information, we can see that the exception is thrown after the readJavaType method is called in the AbstractJackson2HttpMessageConverter class.

Step by step, we found the most critical point. In the _ parseDate method of the DeserializationContext class, we threw an exception after executing df.parse (dateStr).

Public Date parseDate (String dateStr) throws IllegalArgumentException {try {DateFormat df = getDateFormat (); / / this line of code reported an error return df.parse (dateStr);} catch (ParseException e) {throw new IllegalArgumentException (String.format ("Failed to parseDate value'% s:% s", dateStr, e.getMessage ());}}

DeserializationContext is a context for deserialization of jackson, so where does its DateFormat come from? Let's take a look at the source code of getDateFormat.

Protected DateFormat getDateFormat () {if (_ dateFormat! = null) {return _ dateFormat;} DateFormat df = _ config.getDateFormat (); _ dateFormat = df = (DateFormat) df.clone (); return df;}

DateFormat comes from MapperConfig again. Let's take a look at the source code of config.getDateFormat ().

Public final DateFormat getDateFormat () {return _ base.getDateFormat ();}

We know that SpringMvc integrates jackson through the AbstractJackson2HttpMessageConverter class, which maintains the ObjectMapper of jackson, and ObjectMapper is configured through MapperConfig

Thus, this exception is caused by the inability of DateFormat in ObjectMapper to convert strings in yyyy-MM-dd HH:mm:ss format.

The first way to deal with problems

Add annotations to the time attribute for automatic conversion.

The second way

The abnormal value server returned a json with a date in the form of a string 2018-03-07 16 jackson 18Suzhou 35 Jackson cannot convert the string into a Date object and look up data on the Internet. It is said that jackson only supports the following date formats:

"yyyy-MM-dd'T'HH:mm:ss.SSSZ"

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

"yyyy-MM-dd"

"EEE, dd MMM yyyy HH:mm:ss zzz"

Timestamp of type long

Remove the following two configurations on the server and return the date to the timestamp, and the result is correct.

# spring.jackson.date-format=yyyy-MM-dd HH:mm:ss#spring.jackson.time-zone=Asia/Chongqing

Since the server may be coupled to the configuration here elsewhere, that is, it is possible to use yyyy-MM-dd HH:mm:ss as a date format rather than a timestamp format, so this configuration must not be modified.

It must be annoying that jackson doesn't support this format of yyyy-MM-dd HH:mm:ss, so let's take a look at how to get jackson to support this format.

For jackson to support this format, you must modify the DateFormat in ObjectMapper, because in ObjectMapper, the default implementation class for DateFormat is StdDateFormat,StdDateFormat, which is only compatible with the formats we mentioned above.

First, let's use the decoration mode to create a DateFormat that supports the yyyy-MM-dd HH:mm:ss format as follows

Import java.text.DateFormat;import java.text.FieldPosition;import java.text.ParseException;import java.text.ParsePosition;import java.text.SimpleDateFormat;import java.util.Date; public class MyDateFormat extends DateFormat {private DateFormat dateFormat; private SimpleDateFormat format1 = new SimpleDateFormat ("yyy-MM-dd HH:mm:ss"); public MyDateFormat (DateFormat dateFormat) {this.dateFormat = dateFormat } @ Override public StringBuffer format (Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {return dateFormat.format (date, toAppendTo, fieldPosition);} @ Override public Date parse (String source, ParsePosition pos) {Date date = null; try {date = format1.parse (source, pos) } catch (Exception e) {date = dateFormat.parse (source, pos);} return date;} / / mainly decorate this method @ Override public Date parse (String source) throws ParseException {Date date = null Try {/ / first follow my rules date = format1.parse (source);} catch (Exception e) {/ / No, then follow the original rules date = dateFormat.parse (source) } return date;} / / the reason why the clone method is decorated here is that the clone method is also used in jackson @ Override public Object clone () {Object format = dateFormat.clone (); return new MyDateFormat ((DateFormat) format);}}

With DateFormat, the next task is to let ObjectMapper use my DateFormat, which is defined in the config class as follows (this case is based on springboot)

@ Configurationpublic class WebConfig {@ Autowired private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder; @ Bean public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter () {ObjectMapper mapper = jackson2ObjectMapperBuilder.build (); / / ObjectMapper to ensure thread safety, the configuration classes in it are all immutable objects / / so the internal principle of setDateFormat here is to create a new configuration class DateFormat dateFormat = mapper.getDateFormat () Mapper.setDateFormat (new MyDateFormat (dateFormat)); MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter (mapper); return mappingJsonpHttpMessageConverter;}}

After configuring the above code, the problem was resolved successfully.

Why would you use this Converter when you inject MappingJackson2HttpMessageConverter,springMvc into a spring container?

View the source code of springboot as follows:

@ Configurationclass JacksonHttpMessageConvertersConfiguration {@ Configuration@ConditionalOnClass (ObjectMapper.class) @ ConditionalOnBean (ObjectMapper.class) @ ConditionalOnProperty (name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "jackson", matchIfMissing = true) protected static class MappingJackson2HttpMessageConverterConfiguration {@ Bean @ ConditionalOnMissingBean (value = MappingJackson2HttpMessageConverter.class, ignoredType = {"org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter" "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter"}) public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter (ObjectMapper objectMapper) {return new MappingJackson2HttpMessageConverter (objectMapper) }}

The default configuration is that it will only be created when there is no MappingJackson2HttpMessageConverter instance in the spring container.

The idea of springboot is that convention is better than configuration, that is to say, springboot provides us with Converter of spring mvc by default. If we do not have a custom Converter, the framework will create one for us. If we have a custom, then springboot will directly use the bean we registered to bind it.

At this point, I believe that everyone on the "Feign date format conversion errors how to solve" have a deeper understanding, might as well to practical operation it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report