Home Web Front-end JS Tutorial SpringMVC restful annotation @RequestBody converts json and object_javascript skills

SpringMVC restful annotation @RequestBody converts json and object_javascript skills

May 16, 2016 pm 03:26 PM

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;
  }
Copy after login

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<&#63;>> 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 !!!!!");
  }
}
Copy after login

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<&#63;>> 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());
    }
  }
Copy after login

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<&#63;> contextClass = methodParam.getContainingClass();
    Class<T> targetClass = (Class<T>) ResolvableType.forType(targetType,
        ResolvableType.forMethodParameter(methodParam)).resolve();
    for (HttpMessageConverter<&#63;> converter : this.messageConverters) {
      if (converter instanceof GenericHttpMessageConverter) {
        GenericHttpMessageConverter<&#63;> genericConverter = (GenericHttpMessageConverter<&#63;>) 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);
  }
Copy after login

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);
    }
Copy after login

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.

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

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...

Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

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.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

Is JavaScript hard to learn? Is JavaScript hard to learn? Apr 03, 2025 am 12:20 AM

Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

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. �...

See all articles