In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces the "SpringMVC date format attributes automatically converted to timestamps", in the daily operation, I believe that many people have doubts in SpringMVC to achieve date format attributes automatically converted into timestamps. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful for you to answer the doubts of "SpringMVC to automatically convert date format attributes into timestamps". Next, please follow the editor to study!
Background introduction
In the micro-service system built by SpringMVC, the back-end database uses the Long type to store the time type, while the front-end framework tends to use the standard display format of yyyy-MM-dd HH:mm:ss. The front-end JSON request message needs format conversion to interact with the background interface, and this part of the conversion function is realized by the background.
When using it, we find that the time format of the JSON request defined by the front end is yyyy-MM-dd HH:mm:ss, and if the corresponding attribute of the POJO defined in the background is of Long type, it can be automatically converted into a timestamp.
Framework selection, version and main functions
Spring boot 2.1.6.RELEASE
Spring cloud Greenwich.SR3
Alibaba fastjson 1.2.60
Note that the json framework uses fastjson
Code demonstration
For demonstration purposes, define a very simple POJO class:
Public class DateReq {private String dateFormat; private Long timest / / omit getter/setter/toString method}
Then define a simple Controller method:
RestControllerpublic class DemoController {@ PostMapping (value = "/ json/demo/info") public ApiResponse dateJson (@ RequestBody DateReq request) {System.out.println (request);}}
The request message is as follows:
{"dateFormat": "2020-08-07 18:50:00", "timestamp": "2020-08-07 18:50:00"}
The result of the response: DateReq {dateFormat='2020-08-07 18 virtual 50 timestamp=1596797400000}
From the results, we can find that in the dateFormat field, we define the String type, and timestamp defines the Long type. The two fields of the request message use the same value, but in the Controller method, timestamp automatically becomes the timestamp of the Long type and is converted according to East 8.
Here we can get an experience: the POJO time format can be automatically converted to a Long type timestamp, the default time zone is taken from the operating system's time zone, or it is set through the jvm parameter-Duser.timezone=GMT+08.
Source code reading
Now that we have seen the effect of automatic conversion, we are very curious about how the framework is implemented, so we look for the stack through breakpoints:
Deserialze:79, LongCodec (com.alibaba.fastjson.serializer) parseField:85, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer) parseField:1224, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) deserialze:850, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) parseRest:1538, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) deserialze:-1, FastjsonASMDeserializer_3_DateReq (com.alibaba.fastjson.parser.deserializer) deserialze:284, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer) parseObject:692 DefaultJSONParser (com.alibaba.fastjson.parser) parseObject:383, JSON (com.alibaba.fastjson) parseObject:448, JSON (com.alibaba.fastjson) parseObject:556, JSON (com.alibaba.fastjson) readType:263, FastJsonHttpMessageConverter (com.alibaba.fastjson.support.spring) read:237, FastJsonHttpMessageConverter (com.alibaba.fastjson.support.spring) readWithMessageConverters:204, AbstractMessageConverterMethodArgumentResolver (org.springframework.web.servlet.mvc.method.annotation) readWithMessageConverters:157, RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation) resolveArgument:130 RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation) resolveArgument:124, HandlerMethodArgumentResolverComposite (org.springframework.web.method.support)
Two valuable pieces of information were found:
The trigger message type conversion class is FastJsonHttpMessageConverter
The real completion of type mapping is the fastjson framework
With this in mind, when you read the source code, you can focus on fastjson, deserialize from JSON to POJO,Long type field processing, and find this code:
Public T deserialze (DefaultJSONParser parser, Type clazz, Object fieldName) {JSONLexer lexer = parser.lexer; Long longObject; try {int token = lexer.token (); if (token = = 2) {long longValue = lexer.longValue (); lexer.nextToken (16); longObject = longValue } else if (token = = 3) {BigDecimal number = lexer.decimalValue (); longObject = TypeUtils.longValue (number); lexer.nextToken (16);} else {if (token = = 12) {JSONObject jsonObject = new JSONObject (true); parser.parseObject (jsonObject) LongObject = TypeUtils.castToLong (jsonObject);} else {Object value = parser.parse (); / / follow this line, yyyy-MM-dd HH:mm:ss will execute this line of code longObject = TypeUtils.castToLong (value) } if (longObject = = null) {return null;} catch (Exception var9) {throw new JSONException ("parseLong error, field:" + fieldName, var9);} return clazz = = AtomicLong.class? New AtomicLong (longObject): longObject;}
Focus on longObject = TypeUtils.castToLong (value);, the data in yyyy-MM-dd HH:mm:ss format will execute this line of code and follow in to check the source code:
Public static Long castToLong (Object value) {if (value = = null) {return null;} else if (value instanceof BigDecimal) {return longValue ((BigDecimal) value);} else if (value instanceof Number) {return ((Number) value). LongValue ();} else {if (value instanceof String) {String strVal = (String) value If (strVal.length () = = 0 | | "null" .equals (strVal) | | "NULL" .equals (strVal)) {return null;} if (strVal.indexOf (44)! = 0) {strVal = strVal.replaceAll (",", ") } try {return Long.parseLong (strVal);} catch (NumberFormatException var4) {/ / make the last struggle in the exception. Today's case is JSONScanner dateParser = new JSONScanner (strVal); Calendar calendar = null. If (dateParser.scanISO8601DateIfMatch (false)) {calendar = dateParser.getCalendar ();} dateParser.close (); if (calendar! = null) {return calendar.getTimeInMillis () } if (value instanceof Map) {Map map = (Map) value; if (map.size () = = 2 & & map.containsKey ("andIncrement") & & map.containsKey ("andDecrement")) {Iterator iter = map.values () .iterator () Iter.next (); Object value2 = iter.next (); return castToLong (value2);} throw new JSONException ("can not cast to long, value:" + value);}}
You can see that in the castToLong method, various hypothetical processing is made for hypothetical data types. Unfortunately, the data format we experimented with is the last struggle completed in the NumberFormatException exception, using the request data received by the JSONScanner class.
You can see here that the data is parsed by calling dateParser.scanISO8601DateIfMatch, and the calendar object instance is obtained. Finally, the timestamp is obtained through calendar. The scanISO8601DateIfMatch method logic is very complex, with a total of more than 450 lines. Here we capture some of them to show them:
Private boolean scanISO8601DateIfMatch (boolean strict, int rest) {if (rest)
< 8) { return false; } char c0 = charAt(bp); char c1 = charAt(bp + 1); char c2 = charAt(bp + 2); char c3 = charAt(bp + 3); char c4 = charAt(bp + 4); char c5 = charAt(bp + 5); char c6 = charAt(bp + 6); char c7 = charAt(bp + 7); if ((!strict) && rest >13) {char c_r0 = charAt (bp + rest-1); char c_r1 = charAt (bp + rest-2);} char c10; if (rest < 9) {return false;} char c8 = charAt (bp + 8); char c9 = charAt (bp + 9); int date_len = 10 Char y0, y1, y2, y3, M0, M1, d0, D1; if ((c4 = ='-'& & c7 = ='-') / / cn | | (c4 = ='/'& & c7 = ='/') / / tw yyyy/mm/dd) {y0 = c0; y1 = C1; y2 = c2; y3 = c3 M0 = c5; M1 = c6; D0 = c8; D1 = c9;} else if ((c4 = ='-'& & c6 = ='-') / / cn yyyy-m-dd) {y0 = c0; y1 = C1; y2 = c2; y3 = c3; M0 ='0' M1 = c5; if (c8 = ='') {d0 = '013; D1 = c7; date_len = 8;} else {d0 = c7; D1 = c8; date_len = 9 }} else if ((c2 = ='. & & c5 = ='.) / / de dd.mm.yyyy | (c2 = ='-'& & c5 = ='-') / / in dd-mm-yyyy) {d0 = c0; D1 = C1; M0 = c3; M1 = c4; Y0 = c6 Y1 = c7; y2 = c8; y3 = c9;} else if (c8 = ='T') {y0 = c0; y1 = C1; y2 = c2; y3 = c3; M0 = c4; M1 = c5; D0 = c6; D1 = c7 Date_len = 8;} else {if (c4 = = 'year' | | c4 = = 'years') {y0 = c0; y1 = C1; y2 = c2; y3 = c3; if (c7 = = 'month' | c7 = = 'years') {M0 = c5 M1 = c6; if (c9 = = 'day' | | c9 = = 'day') {d0 = '0century; D1 = c8;} else if (charAt (bp + 10) = =' day'| | charAt (bp + 10) = = 'day') {D0 = C8 D1 = c9; date_len = 11;} else {return false;}} else if (c6 = = 'month' | | c6 = = 'month') {M0 = '0mm; M1 = c5 If (c8 = = 'day' | | c8 = = 'day') {d0 = '0century; D1 = c7;} else if (c9 = =' day'| | c9 = = 'day') {D0 = c7; D1 = c8 } else {return false;}} else {return false;}} else {return false }} if (! checkDate (y0, y1, y2, y3, M0, M1, d0, D1)) {return false;} setCalendar (y0, y1, y2, y3, M0, M1, d0, D1); char t = charAt (bp + date_len); if (charAt (bp + date_len + 3)! =':) {return false } if (charAt (bp + date_len + 6)! =':') {return false;} char h0 = charAt (bp + date_len + 1); char H2 = charAt (bp + date_len + 2); char M0 = charAt (bp + date_len + 4); char M1 = charAt (bp + date_len + 5) Char S0 = charAt (bp + date_len + 7); char S1 = charAt (bp + date_len + 8); if (! checkTime (h0, H2, M0, M1, s0, S1) {return false;} setTime (h0, H2, M0, M1, S0, S1); char dot = charAt (bp + date_len + 9); int millisLen =-1 / / there may be no millisecond region, and when there is no millisecond region, the next character position may be'Z','+','- 'int millis = 0; calendar.set (Calendar.MILLISECOND, millis); int timzeZoneLength = 0; char timeZoneFlag = charAt (bp + date_len + 10 + millisLen); if (timeZoneFlag = =') {millisLen++ TimeZoneFlag = charAt (bp + date_len + 10 + millisLen);} char end = charAt (bp + (date_len + 10 + millisLen + timzeZoneLength)); if (end! = EOI & & end! ='") {return false;} ch = charAt (bp + = (date_len + 10 + millisLen + timzeZoneLength)); token = JSONToken.LITERAL_ISO8601_DATE; return true;}
There are still many supported formats, but basically in line with domestic date usage habits, such as 2020-08-08 and 2020-08-08, or even August 8, 2020, the idea of parsing is to intercept the judgment by bit, and then as a parameter of Calendar, the above excerpt code is deleted, if you are interested, you can check the original code.
At this point, the study of "SpringMVC to automatically convert date format attributes to timestamps" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.