


SpringMVC restful annotation @RequestBody converts json and object_javascript skills
Due to the upcoming Chinese New Year, the project team did not have many tasks, so I had some free time to study restful calls in spring. I found that spring has become so powerful that programmers no longer need to care about data conversion and invocation in the process of writing interfaces, and only need to focus on business. Below I summarize the steps and the problems encountered during the research process.
Steps:
1. git clone https://github.com/spring-guides/gs-rest-service.git Downloaded the source code from the spring official website
2. Compile with maven (gradle is also acceptable)
3. Run and visit http://localhost:8080/greeting
4. The running result can convert the object into a json object and return it to the page
At this time, I was thinking about how to automatically convert the requested data into a java object. Through google, I found that spring has actually provided the HttpMessageConverter converter, and MappingJackson2HttpMessageConverter (json ~object conversion class) is loaded by default. ). Just configure @RequestBody Greeting gree to use.
The controller layer code is as follows:
@RequestMapping(value = "/greeting", method = RequestMethod.POST,consumes = "application/json") public @ResponseBody Greeting greeting(@RequestBody Greeting gree) { System.out.println(gree.getContent()); return gree; }
At this time, I made a call through Google’s plug-in (postman), but the life-or-death call was unsuccessful!
Analyze and solve problems:
At this time I feel that the cause of the problem may be in the following aspects:
1. Spring does not load MappingJackson2HttpMessageConverter by default (I don’t know the specific loading method)
2. MappingJackson2HttpMessageConverter cannot work after loading (I don’t know the reason why it does not work)
In fact, the reason why it didn’t work in the end was that I believed too much in the source code of spring (the object did not provide a set method). With these two questions, massive searchers on the Internet could not find the corresponding results. There is no way but to find the root cause of the problem and look at the spring source code.
For the first question:
Step 1: Manually rewrite the loading type converter
@Configuration @EnableWebMvc public class WebConfiguration extends WebMvcConfigurerAdapter { public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) { System.out.println("init convert is start !!!!!"); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setWriteAcceptCharset(false); messageConverters.add(new MappingJackson2HttpMessageConverter()); System.out.println("init convert is stop !!!!!"); } }
The test found that it still cannot be used, and now the reason is even less clear. You can only see how spring loads the type converter by default. It turns out that in the method addDefaultHttpMessageConverters in WebMvcConfigurationSupport (the keyword HttpMessageConverter is reflected and searched for where it is used, it is found through judgment and tracking) as follows:
@SuppressWarnings("deprecation") protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setWriteAcceptCharset(false); messageConverters.add(new ByteArrayHttpMessageConverter()); messageConverters.add(stringConverter); messageConverters.add(new ResourceHttpMessageConverter()); messageConverters.add(new SourceHttpMessageConverter<Source>()); messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { messageConverters.add(new AtomFeedHttpMessageConverter()); messageConverters.add(new RssChannelHttpMessageConverter()); } if (jaxb2Present) { messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { messageConverters.add(new MappingJackson2HttpMessageConverter()); } else if (jacksonPresent) { messageConverters.add(new org.springframework.http.converter.json.MappingJacksonHttpMessageConverter()); } }
The corresponding default converter has been loaded. Breakpoint debugging shows that there is no problem with the default configuration.
It can only be said that it is caused by the second problem, but I don’t know why it caused this problem (json data problem, or other problems). Without knowing the problem, I can only look at the request request and see how the converter works. working. Because I don't know much about spring, I don't know its principle. In this case, the corresponding usage can only be found based on the (HttpMessageConverter) key class. Use experience to judge and debug. It is found that the readWithMessageConverters method in AbstractMessageConverterMethodArgumentResolver is the processing method for request request to perform type conversion.
protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter methodParam, Type targetType) throws IOException, HttpMediaTypeNotSupportedException { MediaType contentType; try { contentType = inputMessage.getHeaders().getContentType(); } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotSupportedException(ex.getMessage()); } if (contentType == null) { contentType = MediaType.APPLICATION_OCTET_STREAM; } Class<?> contextClass = methodParam.getContainingClass(); Class<T> targetClass = (Class<T>) ResolvableType.forType(targetType, ResolvableType.forMethodParameter(methodParam)).resolve(); for (HttpMessageConverter<?> converter : this.messageConverters) { if (converter instanceof GenericHttpMessageConverter) { GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter; if (genericConverter.canRead(targetType, contextClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + targetType + "] as \"" + contentType + "\" using [" + converter + "]"); } return genericConverter.read(targetType, contextClass, inputMessage); } } if (targetClass != null) { if (converter.canRead(targetClass, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + targetClass.getName() + "] as \"" + contentType + "\" using [" + converter + "]"); } return ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage); } } } throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes); }
At this time, it was discovered that the corresponding type message converter MappingJackson2HttpMessageConverter had been found according to the canRead method of HttpMessageConverter, and the conversion had started, but a runtime exception was thrown. Because the exception is not output on the console. Through breakpoint debugging, I found that the readJavaType method of MappingJackson2HttpMessageConverter threw a runtime exception. Through the source code, I found that the bottom layer is operated by Jackson's objectMapper. The code is as follows:
try { return this.objectMapper.readValue(inputMessage.getBody(), javaType); } catch (IOException ex) { throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex); }
If I take out the code separately and run it in the main method, but it still doesn’t work, then I can locate the problem. Either the type is wrong or the input data is wrong. After careful inspection, I found that there is no problem with the json data, and it can also be converted using jsonobject. At this time, it can only be judged that there is a problem with the incoming javaType. If I open it and find that the object (Greeting) does not have a set method, I wonder if it is because jakson cannot work (the principle is not clear). If so, I provide the set method for this object and it can be run again. After going around in a circle, I finally solved the problem, but through this problem, I became more aware of the working mechanism of spring's restful.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

This tutorial will explain how to create pie, ring, and bubble charts using Chart.js. Previously, we have learned four chart types of Chart.js: line chart and bar chart (tutorial 2), as well as radar chart and polar region chart (tutorial 3). Create pie and ring charts Pie charts and ring charts are ideal for showing the proportions of a whole that is divided into different parts. For example, a pie chart can be used to show the percentage of male lions, female lions and young lions in a safari, or the percentage of votes that different candidates receive in the election. Pie charts are only suitable for comparing single parameters or datasets. It should be noted that the pie chart cannot draw entities with zero value because the angle of the fan in the pie chart depends on the numerical size of the data point. This means any entity with zero proportion

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...
