SpringMVC's JSON return & exception handling mechanism (teaching you new SpringMVC martial arts secrets)

Table of contents

Edit

Preface

1. Cheats 1: JSON return

1. Introduction to JSON

1.1 What is JSON return

1.2 Purpose of JSON return

2. Application of JSON return in SpringMVC

2.1 Import dependencies

 2.2 Configure spring-mvc.xml

 2.3 Use of @ResponseBody annotation

2.3.1 What is the @ResponseBody annotation

2.3.2 Preparation for test work

Methods needed to write tests

 ClazzMapper.java, interface class and interface implementation class code

controller code

2.3.3 Run test results

Result 1: /list

Result 2: /load 

Result three: /mapList

Result 4:/mapLoad

Result 5: /all

Result 6:/jsonStr

 2.3.4 Precautions

2. Cheats 2: Exception handling mechanism

1. What is exception handling mechanism

2. Main parts of the exception handling mechanism

3. Exception handling ideas

4. Why global exception handling is needed

5. SpringMVC exception classification

6. Comprehensive case application

1. Method 1: Simple exception handler provided by springmvc

 2. Method 2: Create a global exception class to solve

 3. Method three: @ControllerAdvice and @ExceptionHandler completed


Preface

        In the last blog, we shared new knowledge about JSR303 and interceptors in SpringMVC. We hope it will help you and increase your knowledge. Today I will continue to bring you SpringMVC’s new martial arts secrets - JSON and exception handling mechanisms. One is about data echoing, and the other is about running exception handling. Let’s take a look at it together.

1. Cheats 1: JSON return

1. Introduction to JSON

1.1 What is JSON return

        JSON return means that in network requests, the data format returned by the server is JSON (JavaScript Object Notation) format. JSON is a lightweight data exchange format commonly used for front-end and back-end data transmission and communication . In the JSON return, the server organizes the data in the form of key-value pairs, and represents the structure and content of the data through keys and corresponding values. The client can parse the JSON data and use the corresponding key to obtain the corresponding value for subsequent processing and display. JSON returns are usually used for data transmission in API interfaces and can deliver structured data flexibly and efficiently.

1.2 Purpose of JSON return

The role of JSON return
use illustrate
data transmission By returning data to the client in JSON format, structured data can be effectively delivered for easy parsing and processing by the client.
API interface API interfaces make data interaction between different platforms and systems simpler and more reliable by defining a unified data format (usually JSON).
data storage JSON returns can store data in a way that is easy to read and parse. Many applications store data in files or databases in JSON format for subsequent reading and use.
Front-end rendering JSON returns enable front-end developers to directly process and display data passed by the back-end.
mobile development The backend usually returns data to the client in JSON, allowing the client to parse and display the data. This can achieve the separation of front-end and back-end and improve the performance and response speed of mobile applications.

2. Application of JSON return in SpringMVC

2.1 Import dependencies

Add some code to the pom.xml file

<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.2 Configure spring-mvc.xml

The configuration code is as follows

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

 2.3 Use of @ResponseBody annotation

2.3.1 What is the @ResponseBody annotation

        The @ResponseBody annotation is an annotation used to mark methods or classes. It is commonly used in server-side web development. Its function is to indicate that the return value of the method should be sent directly to the client as the content of the response, rather than being parsed as a view name. It is typically used with the Spring framework’s @Controller or @RestController annotations .

        When a method is annotated with @ResponseBody, the Spring framework will automatically convert the object returned by the method (usually a Java object) into a suitable data format, such as JSON, XML, etc., and then send it to the client as an HTTP response body. This approach makes it easier for developers to return structured data to the client without having to manually convert and format the data.

        The @ResponseBody annotation can be applied to methods in the controller (Controller) or to the entire class, so that all methods of the class will return the return value and send it to the client as the response content.

Note:

        After using this annotation, the view parser will no longer 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.

2.3.2 Preparation for test work
Methods needed to write tests

ClazzMapper.xml

<select id="mapListPager" resultType="java.util.Map" parameterType="com.yx.model.Clazz" >
    select
    <include refid="Base_Column_List" />
    from t_struts_class
    <where>
      <if test="cname != null">
        and cname like concat('%',#{cname},'%')
      </if>
    </where>
  </select>
 ClazzMapper.java, interface class and interface implementation class code
package com.yx.mapper;

import com.yx.model.Clazz;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public interface ClazzMapper {
    int deleteByPrimaryKey(Integer cid);

    int insert(Clazz record);

    int insertSelective(Clazz record);

    Clazz selectByPrimaryKey(Integer cid);

    int updateByPrimaryKeySelective(Clazz record);

    int updateByPrimaryKey(Clazz record);

    List<Clazz> ListPager(Clazz clazz);

    List<Map> mapListPager(Clazz clazz);
}
//===========================以上是ClazzMapper.java代码====================================
//===========================以下是ClazzBiz接口代码====================================
package com.yx.biz;

import com.yx.model.Clazz;
import com.yx.utils.PageBean;

import java.util.List;
import java.util.Map;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:28
 */
public interface ClazzBiz {
    int deleteByPrimaryKey(Integer cid);

    int insert(Clazz record);

    int insertSelective(Clazz record);

    Clazz selectByPrimaryKey(Integer cid);

    int updateByPrimaryKeySelective(Clazz record);

    int updateByPrimaryKey(Clazz record);

    List<Clazz> ListPager(Clazz clazz, PageBean pageBean);

    List<Map> mapListPager(Clazz clazz, PageBean pageBean);
}
//===========================以下是ClazzBizImpl接口实现类代码====================================
package com.yx.biz.Impl;

import com.yx.biz.ClazzBiz;
import com.yx.mapper.ClazzMapper;
import com.yx.model.Clazz;
import com.yx.utils.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:47
 */
@Service
public class ClazzBizImpl implements ClazzBiz {
@Autowired
private ClazzMapper clazzMapper;

    @Override
    public int deleteByPrimaryKey(Integer cid) {
        return clazzMapper.deleteByPrimaryKey(cid);
    }

    @Override
    public int insert(Clazz record) {
        return clazzMapper.insert(record);
    }

    @Override
    public int insertSelective(Clazz record) {
        return clazzMapper.insertSelective(record);
    }

    @Override
    public Clazz selectByPrimaryKey(Integer cid) {
        return clazzMapper.selectByPrimaryKey(cid);
    }

    @Override
    public int updateByPrimaryKeySelective(Clazz record) {
        return clazzMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Clazz record) {
        return clazzMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Clazz> ListPager(Clazz clazz, PageBean pageBean) {
        return clazzMapper.ListPager(clazz);
    }

    @Override
    public List<Map> mapListPager(Clazz clazz, PageBean pageBean) {
        return clazzMapper.mapListPager(clazz);
    }
}

controller code

JsonController.java

package com.yx.web;

import com.yx.biz.ClazzBiz;
import com.yx.model.Clazz;
import com.yx.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;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:25
 */
@Controller
@RequestMapping("/clz/json")
public class JsonController {
    @Autowired
    private ClazzBiz clazzBiz;

    /**
     * 返回List<T>
     * @param req
     * @param clazz
     * @return
     */
    @ResponseBody
    @RequestMapping("/list")
    public List<Clazz> list(HttpServletRequest req, Clazz clazz){
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<Clazz> lst = this.clazzBiz.ListPager(clazz, pageBean);
        return lst;
    }

    /**
     * 返回T
     * @param req
     * @param clazz
     * @return
     */
    @ResponseBody
    @RequestMapping("/load")
    public Clazz load(HttpServletRequest req, Clazz clazz){
        if(clazz.getCid() != null){
            List<Clazz> lst = this.clazzBiz.ListPager(clazz, null);
            return lst.get(0);
        }
        return null;
    }


    /**
     * 返回List<Map>
     * @param req
     * @param clazz
     * @return
     */
    @ResponseBody
    @RequestMapping("/mapList")
    public List<Map> mapList(HttpServletRequest req, Clazz clazz){
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<Map> lst = this.clazzBiz.mapListPager(clazz, pageBean);
        return lst;
    }

    /**
     * 返回Map
     * @param req
     * @param clazz
     * @return
     */
    @ResponseBody
    @RequestMapping("/mapLoad")
    public Map mapLoad(HttpServletRequest req, Clazz clazz){
        if(clazz.getCid() != null){
            List<Map> lst = this.clazzBiz.mapListPager(clazz, null);
            return lst.get(0);
        }
        return null;
    }


    @ResponseBody
    @RequestMapping("/all")
    public Map all(HttpServletRequest req, Clazz clazz){
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<Clazz> lst = this.clazzBiz.ListPager(clazz, pageBean);
        Map map = new HashMap();
        map.put("lst",lst);
        map.put("pageBean",pageBean);
        return map;
    }

    @ResponseBody//返回单个字符串而不是页面
    @RequestMapping("/jsonStr")
    public String jsonStr(HttpServletRequest req, Clazz clazz){
        return "clzEdit";
    }


}
2.3.3 Run test results
Result 1: /list

Result 2: /load 

Result three: /mapList

Result 4:/mapLoad

Result 5: /all

Result 6:/jsonStr

 2.3.4 Precautions
  • When the @ResponseBody label of the method is commented out and the request path of the request/jsonStr method is run, the data will not be displayed and will jump to the /WEB/jsp/clzEdit.jsp page .
  • When all methods in the controller class return json data, you can annotate @ResponseBody on the head of the class.

2. Cheats 2: Exception handling mechanism

1. What is exception handling mechanism

        Exception handling mechanism is a mechanism used in software development to handle errors and exceptions. When a program encounters an error or fails to execute normally, the exception handling mechanism can capture and handle these exceptions to ensure the robustness and reliability of the program.

2. Main parts of the exception handling mechanism

  1. Exception throwing : When an error or abnormal situation occurs within the program, the caller or upper-level code can be notified by throwing an exception.
  2. Exception catching : Handle exceptions by catching exceptions at appropriate locations in the program to avoid program crashes or unpredictable errors.
  3. Exception handling code block : Catch and handle exceptions by using try-catch-finally statement blocks. The try block is used to contain code that may throw exceptions. The catch block is used to catch and handle exceptions. The finally block is used to contain whether an exception occurs or not. All code needs to be executed.
  4. Classification of exception types : Exceptions can be divided into different types, including system exceptions (such as null pointer exceptions, array out-of-bounds exceptions, etc.) and custom exceptions (specific exception types defined in the program).
  5. Exception handling strategies : Depending on different exception types and processing requirements, different exception handling strategies can be adopted, such as terminating program execution, logging, error prompts, etc.

3. Exception handling ideas

  • Detecting exceptions: When the program is running, we must first detect whether an exception has occurred. This can be done through conditional statements, exception catching statements (such as try-catch) or monitoring error codes.

  • Catching exceptions: Once an exception is discovered, an appropriate mechanism needs to be used to catch the exception. When writing code, you can use try-catch statement blocks to catch exceptions that may be thrown. When an exception is thrown, it will jump to the catch code block and perform further processing.

  • Handling exceptions: After catching an exception, appropriate handling measures need to be taken according to the specific situation. This can include outputting error messages, logging, retrying operations, restoring data, throwing new exceptions, terminating the program, etc.

  • Clean up resources: After handling exceptions, make sure that all allocated resources have been released or cleaned up to avoid resource leaks or other problems. Finally code blocks are usually used to implement resource cleanup operations to ensure that the code in finally will be executed regardless of whether an exception occurs.

  • Return results or provide appropriate feedback: According to specific business needs, it is necessary to return the final results or provide relevant feedback information to the user during exception handling. This can help the user better understand the problem and possibly take further action.

Exception handling mechanism diagram

4. Why global exception handling is needed

        We know that exceptions in the system include: compile-time exceptions and runtime exceptions RuntimeException. The former obtains exception information by catching exceptions, and the latter mainly reduces the occurrence of runtime exceptions through standardized code development and testing. During development, whether it is the dao layer, service layer or controller layer, exceptions may be thrown. In springmvc, all types of exception handling can be decoupled from each processing process, which not only ensures that the functions of the relevant processing processes are relatively high. Single, it also realizes unified processing and maintenance of exception information.

5. SpringMVC exception classification

SpringMVC exception classification
abnormal illustrate
Controller layer exception Such exceptions are mainly exceptions thrown by the controller layer (Controller) when processing requests, such as request parameter verification failure, request method not supported, etc.
Business logic exception This type of exception is generally handled by the Service layer, mainly for exceptions generated during business operations, such as data verification failure, resource non-existence, etc. Customized business exceptions can be defined according to specific business requirements and processed uniformly through the global exception handler.
Data access exception This type of exception is mainly thrown by the data access layer (DAO) and is used to represent exceptions that occur when interacting with the database, cache or other external systems, such as database connection disconnection, query results are empty, etc.
System level exception Such anomalies generally refer to operating environment, configuration or other system-related anomalies, such as file read and write errors, network connection problems, etc. These exceptions are usually unpredictable and need to be handled in appropriate ways, such as logging error logs and providing friendly prompts.

6. Comprehensive case application

Write some exceptions in the method and test the display effect in the test later.

 

1. Method 1: Simple exception handler provided by springmvc

Configure downstream code in the spring-mvc.xml file

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

 

error.jsp page code

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/13
  Time: 22:03
  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>
错误信息界面
${ex}

</body>
</html>

Page execution results

Note: The page jump is taken over by SpringMVC, so the default exception handling page defined here should be configured as a logical view name.  

 2. Method 2: Create a global exception class to solve

Exception class GlobalException .java

package com.yx.exception;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:47
 */
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.java

package com.yx.common;

import com.yx.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;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:47
 */
@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{
            mv.addObject("ex",e.getMessage());
            mv.addObject("msg","其他异常....");
        }
        return mv;
    }
}

Writing exceptions

Write jsp code

Test Results

Before testing, the file code in the previous method must be commented, otherwise it will affect the code running test.

 

 3. Method three: @ControllerAdvice and @ExceptionHandler completed

Delete the GlobalExceptionHandler.java file in method 2 and create a GlobalExceptionResolver.java class (the code is as follows)

@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

Uncomment the code of the method that jumps to the error page, and comment out the method of returning the error json data below. The running results are as follows.

 This ends the sharing of this issue. I hope Lao Tie can pay attention to it three times in a row.

Guess you like

Origin blog.csdn.net/weixin_74352229/article/details/132854720