Detail spring mvc4 usage and json date conversion solution

  • 2020-05-30 20:06:03
  • OfStack

When it comes to building a new development environment, it's always important to search the web for the latest frameworks. spring was developed with web framework, and download the latest spring4. 0.3, at the same time, more and more don't want to use struts2, want to try spring mvc, will also be spring - webmvc4. 0.3 down, and in two days after the time to learn and found very elegant, especially since 3.0, spring mvc use annotations way preparation, as well as support for rest style, perfect to the extreme.

The following two days of research to make a summary of the problem, for reference.

1. Acquisition of request objects

Option 1: add the request parameter to the controller method, and spring will be injected automatically, such as:


public String list(HttpServletRequest request,HttpServletResponse response)

Option 2: add the @Resource private HttpServletRequest request property to the controller class, and spring will be injected automatically. It is not known whether there will be threading problems, as one instance of controller will serve multiple requests and has not been tested yet.

Approach 3: write the code fetch directly in the controller method


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();

Approach 4: add the following method to controller, which is executed before the controller processing method is executed


@ModelAttribute 
private void initServlet(HttpServletRequest request,HttpServletResponse response) { 
 //String p=request.getParameter("p"); 
 //this.req=request;// Instance variables, which have thread safety issues, can be used ThreadLocal Mode to save  
} 

2. Acquisition of response objects

You can refer to mode 1 and mode 4 of request above, while mode 2 and mode 3 are invalid for response objects!

3. Data filling of form submission
By directly adding entity object parameters to the method, spring will automatically populate the properties in the object with the name of the object property < input > name1 will be filled, such as:


public boolean doAdd(Demo demo)

4. Data conversion for form submission -Date type

Add @DateTimeFormat (pattern=" yyyy-MM-dd HH:mm:ss") to the properties of the entity class or the get method, and the date string in the form will be correctly converted to Date. There is also the @NumberFormat annotation, which is useless for the moment, so I won't introduce it, but you can see that it is used for number conversion.

5. Return of json data

Add @ResponseBody to the method, and if the method returns an entity object, spring will automatically convert the object to json and return it to the client. As follows:


@RequestMapping("/json1") 
@ResponseBody 
public Demo json1() { 
 Demo demo=new Demo(); 
 demo.setBirthday(new Date()); 
 demo.setCreateTime(new Date()); 
 demo.setHeight(170); 
 demo.setName("tomcat"); 
 demo.setRemark("json test "); 
 demo.setStatus((short)1); 
 return demo; 
} 

Note: spring configuration file to be added: < mvc:annotation-driven/ > , jackson-core.jar, jackson-databind.jar, jackson-es1064en.jar (2.x's package) will be automatically converted to json

This method is provided by spring, and we can also customize the output of json. As mentioned in article 2 above, we can get response objects. After we get response objects, we can let the developer rip them off and return them as they want.

Method does not have a return value, as follows:


@RequestMapping("/json2") 
public void json2() { 
 Demo demo=new Demo(); 
 demo.setBirthday(new Date()); 
 demo.setCreateTime(new Date()); 
 demo.setHeight(170); 
 demo.setName("tomcat"); 
 demo.setRemark("json test "); 
 demo.setStatus((short)1); 
 String json=JsonUtil.toJson(obj);//;json Processing tool class  
 HttpServletResponse response = // To obtain response object  
 response.getWriter().print(json); 
} 

OK, 1 cut is perfect. Then there's the nasty question: when date is converted to json, it returns long time. If you want to return yyyy-MM-dd HH:mm:ss, you have to customize it again. I wonder why you don't use the @DateTimeFormat annotation. Does @DateTimeFormat only convert strings to date types when the form is submitted, but not date types to json strings. With doubts to check the source code, the original spring jackson conversion json characters, and @DateTimeFormat is spring-context package class, jackson how to convert, spring is not convenient to make too much interference, so can only follow the conversion rules of jackson, custom date converter.

Write 1 date converter first, as follows:


public class JsonDateSerializer extends JsonSerializer<Date> { 
 private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 @Override 
 public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) 
   throws IOException, JsonProcessingException { 
  String value = dateFormat.format(date); 
  gen.writeString(value); 
 } 
} 

Configure the use converter on the get method of the entity class, as follows:


@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") 
@JsonSerialize(using=JsonDateSerializer.class) 
public Date getCreateTime() { 
 return this.createTime; 
} 

OK, that's it.

Are you really satisfied with this unelegant solution? Let's say the birthday property looks like this, with only the year, month, day, and hour


@DateTimeFormat(pattern="yyyy-MM-dd") 
public Date getBirthday() { 
 return this.birthday; 
} 

This means customizing it with an JsonDate2Serializer converter and configuring it like this


@DateTimeFormat(pattern="yyyy-MM-dd") 
@JsonSerialize(using=JsonDate2Serializer.class) 
public Date getBirthday() { 
 return this.birthday; 
} 

Assuming there is another Date field in another format, you have to customize another converter for it. Please forgive me my sin and don't make me feel so bad

After analyzing the source code, I found a good scheme, which will no longer use @JsonSerialize, but only use @DateTimeFormat to configure the date format, jackson can be converted correctly, but @DateTimeFormat can only be configured on the get method, it doesn't matter.

First, introduce the following class, which annotates the ObjectMapper class of jackson so that it can also apply date formatting rules to the get method with @DateTimeFormat


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
0

then < mvc:annotation-driven/ > Instead, configure a new json converter and set its ObjectMapper object to objectMapper object in JsonUtil. This converter has a higher priority than spring's built-in json converter, so json related conversions will be used first by spring.


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
1

You can then configure the entity classes in this way, and jackson will also correctly convert the Date type


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
2

Over, all 1 cuts are perfect.

supplement

It turns out that jackson also has a @JsonFormat annotation. After configuring it to Date type get method, jackson will convert the date type according to the configured format instead of customizing the converter class. Hard so much, in fact, others have already provided, just did not find it.

Forget it, go straight to the plan.

1. The spring configuration still looks like this:


<mvc:annotation-driven> 

2.JsonUtil is fine, but if you want to output json from the response object yourself, you can still use json


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
4

3. The get method of the entity class requires an additional @JsonFormat annotation configuration


HttpServletRequest request =((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
5

Related articles: