【SpringMVC】JSON注解&异常处理的使用

2023-09-13 18:20:06

一级目录

一、JSON数据返回

在Web开发中,使用JSON格式返回数据已成为一种常见的做法。本节将介绍如何使用Jackson库实现JSON数据的返回。

1.1 前言

随着移动应用和前后端分离的趋势,使用JSON作为数据传输格式变得越来越流行。在Spring MVC中,我们可以通过配置和使用Jackson库来方便地将Java对象转换为JSON格式的数据并返回给客户端。

1.2 Jackson的介绍

1.2.1 什么是Jackson

Jackson是一个流行的Java库,用于处理JSON格式数据的序列化和反序列化。它提供了一组简单易用的API,可以方便地将Java对象与JSON数据进行转换。

1.2.2 常用注解

在使用Jackson进行JSON序列化和反序列化时,可以使用一些常用的注解来控制转换过程。例如,@JsonProperty可以用于指定JSON属性与Java对象属性之间的映射关系,@JsonFormat可以用于指定日期格式化方式等。

1.3 使用注解

1.3.1 导入依赖
要使用Jackson库,首先需要在项目中导入相应的依赖。可以通过Maven或Gradle来管理依赖。

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

1.3.2 配置spring-mvc.xml

在Spring MVC的配置文件(spring-mvc.xml)中,需要进行一些配置以启用Jackson的支持。可以配置一个MappingJackson2HttpMessageConverter bean,并将其注册到Spring MVC的消息转换器列表中。

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

1.3.3 案例实战

为了演示如何使用Jackson返回JSON数据,我们可以创建一个简单的控制器方法,并使用@ResponseBody注解将其返回的对象转换为JSON格式。

package com.niyin.web;

import com.niyin.excetpion.GlobalException;
import com.niyin.utils.PageBean;
import com.niyin.biz.tyBiz;
import com.niyin.model.ty;
import com.niyin.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;


@ResponseBody
@Controller
@RequestMapping("/clz/json")
public class JsonController {
    @Autowired
    private tyBiz tyBiz;

    /**
     * 返回List<T>
     * @param req
     * @return
     */
//    @ResponseBody
    @RequestMapping("/list")
    public List<ty> list(HttpServletRequest req, ty t){
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<ty> lst = this.tyBiz.selectByPager(t,pageBean);
//        System.out.println(1 / 0);
        return lst;
    }

    /**
     * 返回T
     * @param req
     * @return
     */
//    @ResponseBody
    @RequestMapping("/load")
    public ty load(HttpServletRequest req, ty t){
        if(t.getTid() != null){
            List<ty> lst = this.tyBiz.selectByPager(t,null);
            return lst.get(0);
        }
        return null;
    }


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

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


//    @ResponseBody
    @RequestMapping("/all")
    public Map all(HttpServletRequest req, ty t){
        PageBean pageBean = new PageBean();
        pageBean.setRequest(req);
        List<ty> lst = this.tyBiz.selectByPager(t, pageBean);
        Map map = new HashMap();
        map.put("lst",lst);
        map.put("pageBean",pageBean);
        return map;
    }

//    @ResponseBody
    @RequestMapping("/jsonStr")
    public String jsonStr(HttpServletRequest req, ty t){
//        if (true)
//        throw new GlobalException("你不正经,无理取闹");
        return "clzEdit";

    }


}

返回各种类型数据
list
在这里插入图片描述
load
在这里插入图片描述

mapList
在这里插入图片描述
mapLoad
在这里插入图片描述
all
在这里插入图片描述
jsonStr
在这里插入图片描述

小提示@JsonIgnore 可以用于·隐藏数据。

二、异常处理

异常处理是Web开发中不可避免的一部分。Spring MVC提供了全局异常处理机制,可以统一处理应用程序中的异常情况。

2.1 为什么要全局异常处理

全局异常处理的目的是为了提升系统的稳定性和用户体验。当应用程序抛出异常时,全局异常处理可以捕获并处理这些异常,从而避免将异常信息直接暴露给用户。

2.2 异常处理思路

在设计异常处理机制时,需要考虑以下几个方面:定义自定义异常类、编写异常处理器、配置全局异常处理。

2.3 SpringMVC异常分类

Spring MVC将异常分为两类:可预测的异常和不可预测的异常。可预测的异常是我们在代码中明确捕获并处理的异常,而不可预测的异常是无法预测和处理的异常。

2.4 案例实战

2.4.1 异常处理方式①

SpringMVC中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口。

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

jsp

<%--
  Created by IntelliJ IDEA.
  User: 林墨
  Date: 2023/9/13
  Time: 15:37
  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}
<hr>
${msg}
</body>
</html>

在这里插入图片描述

2.4.2 异常处理方式②

创建一个名为exception的包将我们的GlobalException类放入其中。

package com.niyin.excetpion;

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);
    }
}

创建一个名为Component的包将我们的GlobalExceptionHandler类放入其中。

package com.niyin.component;

import com.niyin.excetpion.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 {
            mv.addObject("ex",e.getMessage());
            mv.addObject("msg","其它异常....");
        }
        return mv;
    }
}

在这里插入图片描述

2.4.3 异常处理方式③

GlobalExceptionResolver.java

package com.niyin.component;

import com.niyin.excetpion.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;
    }
}

这种方式是将我们的错误信息进行map保存然后转换为JSON格式输出在页面上。
在这里插入图片描述

更多推荐

图像识别在自动驾驶和智能安防中的关键应用

图像识别在自动驾驶和智能安防中的关键应用随着人工智能和深度学习技术的发展,图像识别已经成为了自动驾驶和智能安防领域的关键应用之一。图像识别技术能够通过处理和分析图像数据,帮助自动驾驶车辆和智能安防系统实现更准确、更高效的运行。本文将介绍图像识别在自动驾驶和智能安防中的关键应用及其相关技术。一、图像识别在自动驾驶中的应用

设计模式实战:模版方法

1.模版方法概述在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银

并发编程系列-分而治之思想Forkjoin

我们介绍过一些有关并发编程的工具和概念,包括线程池、Future、CompletableFuture和CompletionService。如果仔细观察,你会发现这些工具实际上是帮助我们从任务的角度来解决并发问题的,而不是让我们陷入线程之间如何协作的繁琐细节(比如等待和通知等)。对于简单的并行任务,你可以使用“线程池+F

数据库顶会 VLDB 2023 论文解读 - Krypton: 字节跳动实时服务分析 SQL 引擎设计

“Krypton源于DC宇宙中的氪星,它是超人的故乡,以氪元素命名”。引言近些年,在复杂的分析需求之外,字节内部的业务对于实时数据的在线服务能力也提出了更高的要求。大部分业务不得不采用多套系统来应对不同的Workload,虽然能满足需求,但也带来了不同系统数据一致性的问题,多个系统之间的ETL也浪费了大量的资源,同时对

区块链(1):区块链简介

区快链是通过密码技术保护的分布式数据库这是比特币背后的技术。本文将逐步带您了解区块链。1区块链BLOCKCHAIN的类的定义区块链有一个区块列表。它从一个单独的块开始,称为genesisblock【创世区块】2区块链BLOCK的类的定义第一个区块叫做Genesis[创世]block,每个块存储以下信息:IndexTim

Android 查看按键信息的常用命令详解

Android查看按键信息的常用命令详解文章目录Android查看按键信息的常用命令详解一、主要命令:二、命令详解1、getevent2、getevent-l3、dumsysinput4、catXXX.kl4、cat/dev/input/eventX5、getevent其他命令6、inputkeyeventXX三、简单

【性能测试】JMeter:集合点,同步定时器的应用实例!

一、集合点的定义在性能测试过程中,为了真实模拟多个用户同时进行操作以度量服务器的处理能力,可以考虑同步虚拟用户以便恰好在同一时刻执行操作或发送请求。通过插入集合点可以较真实模拟多个用户并发操作。(注意:虽然通过加入集合点可以约束请求同时发送,但不能确保请求同时到达服务器,所以只能说是较真实模拟并发)在JMeter中可以

Android SurfaceFlinger导读(03)MessageBase

该系列文章总纲链接:AndroidGUI系统之SurfaceFlinger系列文章目录说明:关于导读:导读部分主要是方便初学者理解SurfaceFlinger代码中的机制,为后面分析代码打下一个更好的基础,这样就可以把更多的精力放在surfaceFlinger的业务逻辑分析上。关于代码分支:以下代码分析均在androi

用Jmeter进行压测详解

简介:1.概述一款工具,功能往往是很多的,细枝末节的地方也很多,实际的测试工作中,绝大多数场景会用到的也就是一些核心功能,根本不需要我们事无巨细的去掌握工具的所有功能。所以本文将用带价最小的方式讲解如何快速上手使用jmeter来进行压测。JMeter,一款接口测试工具,是Java程序,需要JDK环境,建议使用JDK8或

GaussDB技术解读系列:高级压缩之OLTP表压缩

8月16日,第14届中国数据库技术大会(DTCC2023)在北京国际会议中心顺利举行。在GaussDB“五高两易”核心技术,给世界一个更优选择的专场,华为云数据库GaussDB首席架构师冯柯对华为云GaussDB数据库的高级压缩技术进行了详细的解读。GaussDB高级压缩全景高级压缩是面向业务全场景的数据库压缩解决方案

优橙内推天津专场——5G网络优化(中高级)工程师

北京电旗通讯技术股份有限公司北京电旗通讯技术股份有限公司(以下简称“电旗”)成立于2001年,是卓越的移动网络工程服务和创新网络智能解决方案供应商,为一级设备供应商,提供包括无线网络及核心网络的规划设计、优化、维护、培训认证及其他相关服务。电旗的总部设在北京,分公司设在北京、台湾、马来西亚、印度和印度尼西亚等四个地区,

热文推荐