[SpringMVC] JSON data return and exception handling (I believe I will understand it after reading this)

Table of contents

1. JSON data return

1. Import dependencies

2. Configuration file

3、Jackson

3.1. Introduction

3.2. Features

3.3. Commonly used annotations

4. Use of @ResponseBody annotation

4.1. Controller layer

4.2, biz layer

4.3、sql.xml

4.4. Page

4.5. Testing

4.6. Pay attention to @ResponseBody

2. Exception handling

1. Why use global exception handling?

2. Exception handling ideas

3. SpringMVC exception classification

4. Abnormal cases

4.1. Exception handling method one

4.2. Exception handling method 2

4.3. Exception handling method three


1. JSON data return

1. Import dependencies

Add the jackson dependency to the pom.xml file in SpringMVC

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.3</version>
</dependency> 

2. Configuration file

Add configuration in your own configured Spring-mvc.xml file

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJackson2HttpMessageConverter"/>
            </list>
        </property>
    </bean>
    <bean id="mappingJackson2HttpMessageConverter"
          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <!--处理中文乱码以及避免IE执行AJAX时,返回JSON出现下载文件-->
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>text/json;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

3、Jackson

3.1. Introduction

Jackson is an open source library for converting Java objects to and from JSON data. It provides a powerful set of APIs that can serialize Java objects into JSON-formatted strings and deserialize JSON strings into Java objects .

The Jackson library consists of three core modules:

  1. Jackson Databind : Used to bind Java objects with JSON data (serialization and deserialization). It provides a series of annotations, such as @JsonProperty , @JsonFormat, etc., which are used to specify the mapping relationship between object properties and JSON fields, as well as the processing methods of special types such as date and time. The Databind module also provides some advanced features, such as polymorphic type processing, bidirectional reference processing, etc.

  2. Jackson Core : Provides core functions for JSON processing, such as JsonParser (used to parse JSON strings), JsonGenerator (used to generate JSON strings) , etc. The Core module also provides serialization and deserialization support for some basic data types and collection types.

  3. Jackson Annotation : Provides some annotations for specifying the name, order, default value and other properties of JSON fields in Java classes. These annotations are used in the Databind module.

Jackson is a simple Java-based application library. Jackson can easily convert Java objects into json objects and xml documents. It can also convert json and xml into Java objects. Jackson relies on fewer jar packages, is easy to use and has relatively high performance. The Jackson community is relatively active and the update speed is relatively fast.

3.2. Features

  • Easy to use, it provides a high-level look and feel that simplifies common use cases.
  • There is no need to create a mapping, the API provides default mappings for most object serialization.
  • High performance, fast, low memory usage
  • Create clean json
  • Does not depend on other libraries
  • Code open source

3.3. Commonly used annotations

The Jackson library provides some commonly used annotations for specifying properties and behaviors related to JSON fields in Java classes.

Common annotations
annotation illustrate
@JsonIgnore
 
Acts on fields or methods to completely ignore the attributes corresponding to the annotated fields and methods.
 
@JsonProperty
 
Acts on fields or methods and is used to serialize/deserialize attributes. It can be used to avoid missing attributes and provide renaming of attribute names.
 
@JsonIgnoreProperties
 
Acts on classes to indicate that some attributes need to be ignored during serialization/deserialization.
 
@JsonUnwrapped
 
Acts on property fields or methods, used to add properties of child JSON objects to the enclosing JSON object
 
@JsonFormat
 
Used to specify special types of formatting methods such as dates and times. The date format can be specified through the pattern attribute of this annotation. For example:
@JsonFormat(pattern="yyyy-MM-dd") private Date birthDate;

  1. @JsonInclude : used to control whether a certain attribute is included during serialization. The conditions for including attributes can be specified through the value attribute of the annotation. For example:

    @JsonInclude(JsonInclude.Include.NON_NULL) private String address;

  2. @JsonAlias : used to specify the mapping relationship between multiple JSON fields and the same Java property. The names of multiple JSON fields can be specified through the value attribute of this annotation. For example:

    @JsonAlias({"firstName", "first_name"}) private String name;

  3. @JsonGetter and @JsonSetter : used to specify the mapping relationship between custom getter and setter methods and JSON fields. For example:

    @JsonGetter("name") public String getUserName() { return userName; }

  4. @JsonAnyGetter and @JsonAnySetter : used to handle undefined properties (i.e. properties not defined in Java classes). These attributes can be dynamically converted into Map or other forms through these annotations. For example:

    @JsonAnyGetter public Map<String, Object> getAdditionalProperties() { return additionalProperties; }

4. Use of @ResponseBody annotation

The @ResponseBody annotation is one of the commonly used annotations in the Spring framework. It is usually used on controller methods or Restful API methods to instruct the results returned by the method to be written directly into the HTTP response body instead of being parsed through the view parser. It can convert the object returned by the method into a specified format, such as JSON, XML or other formats, and return it to the client as an HTTP response body.

Function: After converting the object returned by the Controller method into the specified format through an appropriate converter, it is written into the body area of ​​the response object. It is usually used to return JSON data or XML data.

 Note: After using this annotation, the view parser will not be used , but the data will be written directly to the input stream. Its effect is equivalent to outputting data in the specified format through the response object.

Methods annotated with @ResponseBody can return any type of object as the response body, including ordinary objects, collections, strings, etc. Spring will automatically select the appropriate HttpMessageConverter for conversion based on the " Accept " field in the request header . For example, if " Accept:  http://localhost:8080/json " is specified in the request header , the returned object will be converted into a JSON format string.

4.1. Controller layer

package com.tgq.web;

import com.tgq.biz.MyStudentBiz;
import com.tgq.model.MyStudent;
import com.tgq.utils.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @软件包名 com.tgq.web
 * @用户 tgq
 * @create 2023-09-13 下午2:27
 * @注释说明:
 */
@Controller
//@ResponseBody
//@RestController
@RequestMapping("/sc/json")
public class JsonController {
    @Autowired
    private MyStudentBiz myStudentBiz;

    @RequestMapping("/jsp")
    public String updateByPrimaryKeySelective() {
        return "json/list";
    }

    /**
     * 返回List<T>
     *
     * @param req
     * @param MyStudent
     * @return
     */
    @ResponseBody
    @RequestMapping("/list")
    public List<MyStudent> list(HttpServletRequest req, MyStudent MyStudent) {
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<MyStudent> list = this.myStudentBiz.selectPager(MyStudent, pageBean);
        return list;
    }

    /**
     * 返回T
     *
     * @param req
     * @param MyStudent
     * @return
     */
    @ResponseBody
    @RequestMapping("/load")
    public MyStudent load(HttpServletRequest req, MyStudent MyStudent) {
        if (MyStudent.getSname() != null) {
            List<MyStudent> list = this.myStudentBiz.selectPager(MyStudent, null);
            return list.get(0);
        }
        return null;
    }


    /**
     * 返回List<Map>
     *
     * @param req
     * @param MyStudent
     * @return
     */
    @ResponseBody
    @RequestMapping("/mapList")
    public List<Map> mapList(HttpServletRequest req, MyStudent MyStudent) {
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<Map> list = this.myStudentBiz.mapSelectPager(MyStudent, pageBean);
        return list;
    }

    /**
     * 返回Map
     *
     * @param req
     * @param MyStudent
     * @return
     */
    @ResponseBody
    @RequestMapping("/mapLoad")
    public Map mapLoad(HttpServletRequest req, MyStudent MyStudent) {
        if (MyStudent.getSname() != null) {
            List<Map> list = this.myStudentBiz.mapSelectPager(MyStudent, null);
            return list.get(0);
        }
        return null;
    }


    @ResponseBody
    @RequestMapping("/all")
    public Map all(HttpServletRequest req, MyStudent MyStudent) {
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<MyStudent> list = this.myStudentBiz.selectPager(MyStudent, pageBean);
        Map map = new HashMap();
        map.put("list", list);
        map.put("pageBean", pageBean);
        return map;
    }

    @ResponseBody//注释 跳的就是页面,就不是显示的字符串
    @RequestMapping("/jsonStr")
    public String jsonStr(HttpServletRequest req, MyStudent MyStudent) {
        return "sc-edit";
    }


}

4.2, biz layer

    @Override
    public List<Map> mapSelectPager(MyStudent myStudent, PageBean pageBean) {
        return myStudentMapper.mapSelectPager(myStudent);
    }

4.3、sql.xml

    <select id="mapSelectPager" resultType="java.util.Map" parameterType="com.tgq.model.MyStudent">
        select *
        from t_mysql_student
        <where>
            <if test="sname != null"/>
            and sname like concat('%',#{sname},'%')
        </where>
    </select>

4.4. Page

<%--
  Created by IntelliJ IDEA.
  User: tgq
  Date: 13/9/2023
  Time: 下午2:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>JSON</h3>
<a href="${pageContext.request.contextPath}/sc/json/list?sname=">返回List&lt;T&gt;</a>
<hr>
<a href="${pageContext.request.contextPath}/sc/json/mapList?sname=">返回List&lt;Map&gt;</a>
<hr>
<a href="${pageContext.request.contextPath}/sc/json/load?sname=三">返回T</a>
<hr>
<a href="${pageContext.request.contextPath}/sc/json/mapLoad?sname=三">返回Map</a>
<hr>
<a href="${pageContext.request.contextPath}/sc/json/all?sname=">返回混合</a>
<hr>
<a href="${pageContext.request.contextPath}/sc/json/jsonStr">返回JSON字符串</a>
<hr>
</body>
</html>

4.5. Testing

http://localhost:8080/sc/json/jsp

4.6. Pay attention to @ResponseBody

If you add the @ResponseBody annotation to the class name , all methods inside will return strings .

@RestController : can replace @Controller and @ResponseBody

2. Exception handling

1. Why use global exception handling?

Global exception handling is a way to centrally handle exceptions in an application. Its main purpose is to provide a unified mechanism for handling exceptions thrown in an application, rather than having separate handling at every place where an exception may be thrown.

Benefits of using global exception handling:

  1. Code simplicity : Through global exception handling, we can separate the exception handling logic from the business code, making the business code more concise and clear. The business code only needs to focus on the core business logic and leave exception handling to a dedicated exception handler.

  2. Unified exception handling : Global exception handling provides a unified mechanism to handle exceptions in the application. Whether it is an exception thrown when processing a request in the controller, or an exception thrown in the service layer, persistence layer, or elsewhere , it can be handled in the global exception handler. This ensures that all exceptions in the application can be handled uniformly, improving development efficiency and code quality.

  3. Exception information friendliness : Through global exception handling, we can customize the format and content of exception information to make it more friendly and easy to understand. Based on specific business needs, we can transform the abnormal information into a form suitable for user display, or record it in a log for troubleshooting.

  4. Unified exception return : In global exception handling, we can uniformly define the format and content of exception return. For example, you can define a general error response object to encapsulate exception information and return it to the client uniformly. This avoids having to manually handle exceptions and return error messages in each controller method.

  5. Security : Through global exception handling, we can capture and handle unhandled exceptions to prevent exception information from being exposed to the client, thereby improving application security.

Global exception handling provides a centralized way to handle exceptions in applications, simplifying code logic and improving code readability and maintainability. It allows us to better handle exceptions, optimize user experience, and improve application stability and security.

2. Exception handling ideas

The first way of thinking:

Exceptions in the system's dao, service, and controller are all thrown upward through throws Exception. Finally, the springmvc front-end controller hands it over to the exception handler for exception handling. Springmvc provides a global exception handler (a system has only one exception handler) for unified exception handling.

You can also follow the second idea:

  1. Catch exceptions : Use try-catch statement blocks in your code to catch exceptions that may be thrown. Place code that may throw exceptions in a try block, and handle caught exceptions in a catch block. You can use multiple catch blocks to handle different types of exceptions according to different exception types.

  2. Logging : During the exception handling process, exception information should be recorded to facilitate subsequent troubleshooting and debugging. You can use a logging framework (such as Log4j, Slf4j, etc.) to record exception information, including exception type, exception message, stack trace, etc. Through logging, potential problems can be discovered and solved in time.

  3. Friendly prompts : Based on specific business needs, exception information can be converted into friendly prompt information for users to understand and process. You can set the error code and error message of the exception by customizing the exception class, and then return the corresponding prompt information to the user based on the error code.

  4. Exception return : In web applications, you can use a global exception handler to encapsulate exception information into a unified error response and return it to the client. This provides unified exception handling logic and avoids manual exception handling in each controller method.

  5. Exception chain delivery : After catching an exception, you can throw a new exception or pass the original exception as a parameter to the upper-level caller so that the upper-level caller can handle the exception. Through the exception chain, exception information can be transferred to the appropriate place for processing.

  6. Exception handling strategy : For recoverable exceptions, corresponding handling strategies can be adopted to try to restore normal program execution. For example, you can reconnect to the database, resend the request, etc. For unrecoverable exceptions, relevant personnel can be notified or emergency treatment can be carried out.

  7. Abnormal monitoring and statistics : You can use monitoring tools or log analysis tools to monitor and count abnormalities so that abnormal problems can be discovered and solved in a timely manner. By collecting and analyzing abnormal information, it can help optimize system performance and improve user experience.

The idea of ​​handling exceptions is to capture exceptions, record exceptions, friendly prompts, and return exceptions, adopt appropriate processing strategies according to specific situations , and perform exception monitoring and statistics. Through good exception handling, the stability and maintainability of the application can be improved, the user experience can be optimized, and potential problems can be discovered and solved in a timely manner.

3. SpringMVC exception classification

  • Use the simple exception handler SimpleMappingExceptionResolver provided by Spring MVC; 
  • Implement Spring's exception handling interface HandlerExceptionResolver to customize your own exception handler;
  • 使用@ControllerAdvice + @ExceptionHandler

  1. Controller exceptions : Controller exceptions are exceptions that occur while handling client requests. These exceptions are typically thrown by controller methods and can include validation errors, request parameter errors, etc. You can use @ExceptionHandlerannotations to handle controller exceptions, centralize exception handling logic in one place, and uniformly return error information to the client.

  2. Service layer exceptions : Service layer exceptions are usually caused by business logic, such as data query failure, business rule verification failure, etc. Service layer exceptions should be caught and handled in the service layer. You can use try-catch statement blocks or custom exception handlers to handle service layer exceptions.

  3. Data access exceptions : Data access exceptions are mainly caused by database operations, such as database connection failure, SQL statement execution errors, etc. In Spring MVC, you can use Spring's data access framework (such as Spring Data JPA, MyBatis, etc.) to handle data access exceptions. The framework will automatically convert underlying exceptions into Spring's data access exceptions (such as DataAccessException).

  4. Global exceptions : Global exceptions refer to exceptions that are not caught and handled in the application, or are unpredictable exceptions. You can use a global exception handler ( @ControllerAdviceannotation) to handle global exceptions and concentrate the exception handling logic in one place to uniformly handle and return error information.

  5. Runtime exception : Runtime exception ( RuntimeException ) is an exception that does not need to be explicitly caught and handled. These exceptions are usually caused by program errors or logic errors, such as null pointer exceptions, array out-of-bounds exceptions, etc. In Spring MVC , runtime exceptions will be caught by the Servlet container and return the default error page (such as the 500 Internal Server Error page).

For different types of exceptions, you can choose different handling methods according to specific needs. Some exceptions can be caught and handled to resume normal program execution, while others may require notification to relevant personnel or emergency handling. By properly classifying and handling exceptions, the stability and maintainability of your application can be improved.

4. Abnormal cases

4.1. Exception handling method one

SpringMVC comes with an exception handler called SimpleMappingExceptionResolver , which implements the HandlerExceptionResolver interface. All global exception handlers need to implement this interface.

spring-mvc.xml

<!-- springmvc提供的简单异常处理器 -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面 -->
        <property name="defaultErrorView" value="error"/>
        <!-- 定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception -->
        <property name="exceptionAttribute" value="ex"/>
        <!-- 定义需要特殊处理的异常,这是重要点 -->
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.RuntimeException">error</prop>
            </props>
            <!-- 还可以定义其他的自定义异常 -->
        </property>
    </bean>

Page jumps are taken over by SpringMVC, so the default exception handling pages defined here should be configured as logical view names.

    @RequestMapping("/error")
    public String error(MyStudent MyStudent) {
        MyStudent = null;
        MyStudent.getSname();
        return "error";
    }

Write an unusual interface

<%--
  Created by IntelliJ IDEA.
  User: tgq
  Date: 13/9/2023
  Time: 下午6:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>error</title>
</head>
<body>
错误信息....
${ex}
</body>
</html>

Test the effect

http://localhost:8080/sc/json/error

4.2. Exception handling method 2

Create two packages and write two classes in them

GlobalException 

package com.tgq.exception;

public class GlobalException extends RuntimeException {
    public GlobalException() {
    }

    public GlobalException(String message) {
        super(message);
    }

    public GlobalException(String message, Throwable cause) {
        super(message, cause);
    }

    public GlobalException(Throwable cause) {
        super(cause);
    }

    public GlobalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}


 

GlobalExceptionHandler 

package com.tgq.component;

import com.tgq.exception.GlobalException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class GlobalExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse,
                                         Object o, Exception e) {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error");
        if (e instanceof GlobalException) {
            GlobalException globalException = (GlobalException) e;
            mv.addObject("ex", globalException.getMessage());
            mv.addObject("msg", "全局异常....");
        } else if (e instanceof RuntimeException) {
            RuntimeException runtimeException = (RuntimeException) e;
            mv.addObject("ex", runtimeException.getMessage());
            mv.addObject("msg", "运行时异常....");
        } else if (e instanceof RuntimeException) {
            RuntimeException runtimeException = (RuntimeException) e;
            mv.addObject("ex", e.getMessage());
            mv.addObject("msg", "其他异常....");
        }
        return mv;
    }
}

Exceptions can also be customized later

Write a method test

    @RequestMapping("/error02")
    public String error2(HttpServletRequest req) {
      if (true)
          throw new GlobalException("老异常了");
        return "error";
    }

Page code

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>error</title>
</head>
<body>
错误信息....
${msg}
</body>
</html>

http://localhost:8080/sc/json/error02

4.3. Exception handling method three

You can replace the GlobalExceptionHandler in the component package with GlobalExceptionResolver  GlobalExceptionResolver  : the json format and jump page returned inside

package com.tgq.component;

import com.tgq.exception.GlobalException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionResolver {

//    跳转错误页面
//    @ExceptionHandler
//    public ModelAndView handler(Exception e){
//        ModelAndView mv = new ModelAndView();
//        mv.setViewName("error");
//        if (e instanceof GlobalException){
//            GlobalException globalException = (GlobalException) e;
//            mv.addObject("ex",globalException.getMessage());
//            mv.addObject("msg","全局异常....");
//        }else if (e instanceof RuntimeException){
//            RuntimeException runtimeException = (RuntimeException) e;
//            mv.addObject("ex",runtimeException.getMessage());
//            mv.addObject("msg","运行时异常....");
//        }
//        return mv;
//    }

    // 返回错误json数据
    @ResponseBody
    @ExceptionHandler
    public Map handler(Exception e) {
        Map map = new HashMap();
        if (e instanceof GlobalException) {
            GlobalException globalException = (GlobalException) e;
            map.put("ex", globalException.getMessage());
            map.put("msg", "全局异常....");
        } else if (e instanceof RuntimeException) {
            RuntimeException runtimeException = (RuntimeException) e;
            map.put("ex", runtimeException.getMessage());
            map.put("msg", "运行时异常....");
        } else {
            map.put("ex", e.getMessage());
            map.put("msg", "其它异常....");
        }
        return map;
    }
}

Test Results

json format

page

Guess you like

Origin blog.csdn.net/weixin_74383330/article/details/132852735