目录
一、JSON处理
1.1 导入依赖
1.2 配置Spring-mvc.xml
1.3 @ResponseBody注解使用
编辑
1.4 Jackson
1.4.1 定义
1.4.2 用途
1.4.3 用法
1.4.4 常用注解
1.5 作用
二、统一异常处理
2.1 为什么要全局异常处理?
2.2 异常处理思路
2.3 SpringMVC异常分类
2.4 综合案例
2.4.1 异常处理方式一
2.4.2 异常处理方式二
2.4.3 异常处理方式三
三、收获
一、JSON处理
1.1 导入依赖
<!-- JSON数据返回--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>${jackson.version}</version></dependency>
1.2 配置Spring-mvc.xml
<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 @ResponseBody注解使用
@ResponseBody是一个Spring MVC注解,用于指示方法返回的值应该被序列化为HTTP响应的正文。它被添加到控制器方法中,并告诉Spring MVC框架不要将方法的返回值解释为视图名称或模型数据。相反,该注解告诉Spring MVC将返回值直接写入HTTP响应正文中,这通常是JSON或XML格式。
注:
通常@ResponseBody注解与@RequestMapping注解结合使用,后者指定HTTP方法和请求URL以及其它可选的参数,以告诉Spring MVC如何匹配请求并调用适当的控制器方法。 注意:在使用此注解之后不会再走视图解析器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
创建一个JsonController类,如下:
package com.Kissship.web;import com.Kissship.biz.MusicBiz;
import com.Kissship.exception.GlobalException;
import com.Kissship.model.Music;
import com.Kissship.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("/mic/json")
public class JsonController {@Autowiredprivate MusicBiz musicBiz;/*** 返回List<T>* @param req* @param music* @return*/
// @ResponseBody@RequestMapping("/list")public List<Music> list(HttpServletRequest req, Music music){PageBean pageBean = new PageBean();pageBean.setRequest(req);List<Music> lst = this.musicBiz.listPager(music, pageBean);System.out.println(1/0);return lst;}/*** 返回T* @param req* @param music* @return*/
// @ResponseBody@RequestMapping("/load")public Music load(HttpServletRequest req, Music music){if(music.getMid() != null){List<Music> lst = this.musicBiz.listPager(music, null);return lst.get(0);}return null;}/*** 返回List<Map>* @param req* @param music* @return*/
// @ResponseBody@RequestMapping("/mapList")public List<Map> mapList(HttpServletRequest req, Music music){PageBean pageBean = new PageBean();pageBean.setRequest(req);List<Map> lst = this.musicBiz.mapListPager(music, pageBean);return lst;}/*** 返回Map* @param req* @param music* @return*/
// @ResponseBody@RequestMapping("/mapLoad")public Map mapLoad(HttpServletRequest req, Music music){if(music.getMid() != null){List<Map> lst = this.musicBiz.mapListPager(music, null);return lst.get(0);}return null;}// @ResponseBody@RequestMapping("/all")public Map all(HttpServletRequest req, Music music){PageBean pageBean = new PageBean();pageBean.setRequest(req);List<Music> lst = this.musicBiz.listPager(music, pageBean);Map map = new HashMap();map.put("lst",lst);map.put("pageBean",pageBean);return map;}// @ResponseBody//全局异常@RequestMapping("/jsonStr")public String jsonStr(HttpServletRequest req, Music music){if(true)throw new GlobalException("刘三金说爱她一万年!!!");return "micEdit";}}
然后紧接着在MusicBiz中添加以下代码,如下:
List<Map> mapListPager(Music music, PageBean pageBean);
再在impl类中实现该接口,如下:
@Overridepublic List<Map> mapListPager(Music music, PageBean pageBean) {return musicMapper.mapListPager(music);}
然后根据实现的方法在逆向生成的musicMapper中添加:
List<Map> mapListPager(Music music);
musicMapper.xml:
<select id="mapListPager" resultType="java.util.Map" parameterType="com.Kissship.model.Music" >select*from jay_music<where><if test="mname != null">and mname like concat('%',#{mname},'%')</if></where></select>
添加完毕后,我们开始测试,效果如下:
List集合转Json:
Map集合转JSon:
1.4 Jackson
1.4.1 定义
ackson是一个流行的Java库,用于序列化和反序列化Java对象和JSON数据。它被广泛用于Java应用程序中,包括SpringMVC。
1.4.2 用途
在SpringMVC中,可以使用Jackson来轻松地将Java对象转换为JSON数据和将JSON数据转换为Java对象。这样,可以在SpringMVC应用程序中快速地处理和传输数据。
1.4.3 用法
使用Jackson需要在SpringMVC中添加Jackson依赖,并配置JacksonMessageConverter。JacksonMessageConverter是SpringMVC中的一个消息转换器,用于将Java对象转换为JSON数据和将JSON数据转换为Java对象。
Jackson还支持注解,例如@JsonProperty和@JsonView,可以帮助控制序列化和反序列化的行为。总的来说,Jackson是一个强大的Java库,可以使SpringMVC应用程序更方便地处理和传输数据。
1.4.4 常用注解
在SpringMVC中,使用Jackson进行数据序列化和反序列化是非常方便的。以下是常用的Jackson注解:
1. @JsonFormat:格式化输出日期类型的值
2. @JsonInclude:控制序列化过程中包含哪些属性
3. @JsonIgnore:忽略某些属性
4. @JsonProperty:指定属性的名称
5. @JsonView:根据视图序列化对象
6. @JsonManagedReference和@JsonBackReference:解决对象循环引用的问题
7. @JsonIdentityInfo:为对象设置唯一标识
8. @JsonTypeInfo:序列化和反序列化时带上类型信息
9. @JsonAutoDetect:指定序列化和反序列化过程中哪些属性可见
10. @JsonCreator:定义一个构造函数用于反序列化
11. @JsonAnyGetter和@JsonAnySetter:序列化和反序列化时动态处理属性
1.5 作用
返回JSON数据的作用主要有以下几个方面:
1. 简化数据处理:JSON是一种轻量级的数据交换格式,它的结构简单、易于理解和使用。通过返回JSON数据,可以更加轻松地处理和解析数据,使得前后端的数据交互更加高效和便捷。
2. 支持跨域请求:由于浏览器的同源策略限制,不同域名之间的请求通常是不被允许的。但是通过跨域请求返回JSON数据,可以利用JSONP等技术来实现跨域请求,解决跨域问题,方便进行数据交换。
3. 方便数据序列化和反序列化:将数据序列化为JSON格式可以方便的进行数据的传输和存储,同时在前端解析展示数据时,也可以方便的将JSON数据反序列化为对象,使得数据的传输和处理更加高效和便捷。
4. 支持多语言:JSON是一种跨语言的数据格式,可以在不同的编程语言之间通用,支持多语言的开发和数据交换。
二、统一异常处理
2.1 为什么要全局异常处理?
Java 中的全局异常处理是指在程序中统一处理所有的异常,而不是在每个方法中单独处理异常。使用全局异常处理可以提高代码的可读性和可维护性,减少代码冗余,避免重复代码。此外,全局异常处理可以将异常信息统一记录到日志中,方便后续的问题排查和分析。如果不使用全局异常处理,在出现异常时,程序可能会直接终止,用户体验也会受到影响。因此,在 Java 中使用全局异常处理是一个好的编程实践。
2.2 异常处理思路
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
2.3 SpringMVC异常分类
在SpringMVC中,异常可以分为以下几类:
1. 控制器方法异常:当控制器方法抛出异常时,SpringMVC会将异常信息包装成一个特殊的响应对象返回给客户端。
2. 数据转换异常:当SpringMVC无法将请求参数转换成对应类型的数据时,会抛出数据转换异常。
3. 数据验证异常:当请求参数不符合预定的验证规则时,会抛出数据验证异常。
4. 消息转换异常:当SpringMVC无法将响应数据转换成客户端需要的类型时,会抛出消息转换异常。
5. 文件上传异常:当文件上传过程中出现问题时,会抛出文件上传异常。
6. MVC配置异常:当SpringMVC配置出现问题时,会抛出MVC配置异常。
7. 未处理的异常:当SpringMVC中出现未处理的异常时,会抛出未处理的异常。
2.4 综合案例
2.4.1 异常处理方式一
SpringMVC中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口。
在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>
</beans>
注:页面跳转由SpringMVC来接管了,所以此处的定义默认的异常处理页面都应该配置成逻辑视图名。
新建一个errpr.jsp用来展示异常效果,如下:
<%--Created by IntelliJ IDEA.User: jjDate: 2023/9/13Time: 15:43To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>error</title>
</head>
<body>
错误信息页面。。。
<hr>
${ex}
</body>
</html>
然后造一个错误数据,如下:
@RequestMapping("/mapList")public List<Map> mapList(HttpServletRequest req, Music music){PageBean pageBean = new PageBean();pageBean.setRequest(req);List<Map> lst = this.musicBiz.mapListPager(music, pageBean);System.out.println(1/0);return lst;}
测试结果:
2.4.2 异常处理方式二
首先在异常包中定义一个全局异常的类,如下:
异常类代码如下:
package com.Kissship.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);}
}
创建一个全局异常处理类,代码如下:
package com.Kissship.component;import com.Kissship.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 {@Overridepublic 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 {}return mv;}
}
测试结果如下:
2.4.3 异常处理方式三
注:前两种异常不可同时使用。
定义一个新的异常处理方法,如下:
// 返回错误json数据@ResponseBody@ExceptionHandlerpublic 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;}
测试结果如下:
三、收获
学习SpringMVC的异常处理机制可以带给我们以下收获:
1. 更好的错误处理:异常处理机制可以在应用程序中捕获并处理各种类型的错误,包括运行时错误、网络错误和数据库错误,使得我们能够更好地处理错误,提高应用程序的可靠性和健壮性。
2. 更好的用户体验:异常处理机制可以帮助我们提供更好的用户体验,通过捕获和处理异常,我们可以向用户提供有用的错误信息,帮助他们更好地理解错误原因,并采取适当的措施。
3. 更高的代码可读性:异常处理机制能够使代码更加清晰,减少代码中的嵌套和冗余,提高代码的可读性和可维护性。
4. 更好的安全性:异常处理机制也可以帮助我们处理安全问题,例如防止 SQL 注入攻击等,保护应用程序的安全性。
总体来说,学习SpringMVC的异常处理机制可以帮助我们在开发高质量的Web应用程序时更加自信和有效。
最后SpringMVC之JSON返回及异常处理机制就到这里,祝大家在敲代码的路上一路通畅!