一、Jackson
1.1 Jackson是什么
在Java中,Jackson是一个流行的开源库,用于处理JSON数据。它提供了一组功能强大的API,可以将Java对象序列化为JSON格式,或将JSON数据反序列化为Java对象。Jackson库提供了灵活的方式来处理JSON数据,包括读取、写入、转换和操作JSON对象。它是Java开发人员在处理JSON数据时的常用工具之一。
1.2 常用注解
Jackson库提供了一些常用的注解,用于在Java对象和JSON数据之间进行序列化和反序列化的映射。以下是一些常用的Jackson注解:
- @JsonProperty:用于指定Java对象属性与JSON字段之间的映射关系
- @JsonFormat:用于指定日期、时间等特殊类型属性的格式化方式。
- @JsonIgnore:用于忽略某个属性,不进行序列化和反序列化。 @JsonInclude:用于控制在序列化过程中是否包含某个属性。
- @JsonAlias:用于指定多个JSON字段名与Java对象属性之间的映射关系。
- @JsonCreator:用于指定一个静态工厂方法或构造函数,用于反序列化JSON数据。
- @JsonAnyGetter和@JsonAnySetter:用于处理动态属性,允许将未映射到Java对象属性的JSON字段读取和写入。
1.3 实例
1.3.1导入依赖
<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
<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 JsonController.java
@RequestMapping("/queryListBooks") @ResponseBody public List<Book> queryListBooks(Book book,HttpServletRequest request){ PageBean pageBean=new PageBean(); pageBean.setRequest(request); List<Book> books = bookService.queryBookPager(book, pageBean); return books; }; @RequestMapping("/querySingleBook") @ResponseBody public Book querySingleBook(Integer bookId){ Book book = bookService.selectByPrimaryKey(bookId); book.setDate(new Date()); return book; } @RequestMapping("/querySingleMap") @ResponseBody public Map<String, Object> querySingleMap(Integer bookId){ return bookService.querySingleMap(bookId); } @RequestMapping("/queryMapList") @ResponseBody public List<Map<String, Object>> queryMapList( ){ return bookService.queryBookAll(); } @RequestMapping("/queryString") @ResponseBody public String queryString(){ return "book/bookList"; }
二、Spring MVC异常处理机制
2.1 使用原因
我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。在开发中,不管是(dao/mapper)层、service层还是controller层,都有可能抛出异常。
而在Spring MVC中提供了一个通用的异常处理机制,它提供了一个成熟、简洁并且清晰的异常处理方案。当使用Spring MVC开发Web应用时,利用这套现成的机制进行异常处理也更加自然并且高效。
2.2 SpringMVC异常处理
2.2.1 异常处理机制流程图
系统的Dao(mapper)、Service、Controller出现都通过throws Exception向上抛出,最后SpringMVC前端控制器交由异常处理器进行异常处理,如下图:
2.2.2 异常处理的三种方式
1. 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
SpringMVC中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口
(1)配置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>
(2)方法中抛出此异常
@RequestMapping("/querySingleBook") @ResponseBody public Book querySingleBook(Integer bookId){ Book book = bookService.selectByPrimaryKey(bookId); if(bookId>100) throw new RuntimeException("书本编号大于100,异常抛出!!!"); book.setDate(new Date()); return book; }
2. 实现Spring的异常处理接口HandlerExceptionResolver自定义自己的异常处理器;
(1) 实现HandlerExceptionResolver接口
package com.xqx.exception; 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; /** * SpingMVC提供的第二种全局异常处理方式 ,实现HandlerExceptionResolver接口 */ @Component public class GlobalException implements HandlerExceptionResolver { /** * * @param httpServletRequest * @param httpServletResponse * @param o 异常处理的目标 * @param e 异常处理的类型 * @return */ @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView mv=new ModelAndView(); mv.setViewName("error"); //判断异常的分类 if(e instanceof RuntimeException){ RuntimeException ex=(RuntimeException)e; System.out.println(ex.getMessage()); mv.addObject("msg",ex.getMessage()); } return mv; } }
(2)创建异常类
package com.xqx.exception; 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; /** * SpingMVC提供的第二种全局异常处理方式 ,实现HandlerExceptionResolver接口 */ @Component public class GlobalException implements HandlerExceptionResolver { /** * * @param httpServletRequest * @param httpServletResponse * @param o 异常处理的目标 * @param e 异常处理的类型 * @return */ @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView mv=new ModelAndView(); mv.setViewName("error"); //判断异常的分类 if(e instanceof RuntimeException){ RuntimeException ex=(RuntimeException)e; System.out.println(ex.getMessage()); mv.addObject("msg",ex.getMessage()); } return mv; } }
(3)方法中抛出此异常
@RequestMapping("/querySingleBook") @ResponseBody public Book querySingleBook(Integer bookId){ Book book = bookService.selectByPrimaryKey(bookId); if(bookId>100) throw new BusinessException("书本编号大于100,异常抛出!!!"); book.setDate(new Date()); return book; }
3. 使用@ControllerAdvice + @ExceptionHandler
(1)
package com.xqx.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import java.util.HashMap; import java.util.Map; /** * SpingMVC提供的第三种种全局异常处理方式 * 1)@ControllerAdvice +@ExceptionHandler * 2)@RestControllerAdvice +@ExceptionHandler * @RestControllerAdvice ==@Controller +@ResponseBody 返回JSON的数据格式,绕开视图解析器 */ @ControllerAdvice public class GlobalException2{ @ExceptionHandler public ModelAndView exceptionHandler(Exception e){ ModelAndView mv=new ModelAndView(); //设置错误页面 mv.setViewName("error"); //判断异常类型 if(e instanceof BusinessException){ BusinessException ex=(BusinessException)e; mv.addObject("msg","系统繁忙,请稍后再试......."); } mv.setView(new MappingJackson2JsonView()); return mv; } }
(2) 返回JSON格式
package com.xqx.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import java.util.HashMap; import java.util.Map; /** * SpingMVC提供的第三种种全局异常处理方式 * 1)@ControllerAdvice +@ExceptionHandler * 2)@RestControllerAdvice +@ExceptionHandler * @RestControllerAdvice ==@Controller +@ResponseBody 返回JSON的数据格式,绕开视图解析器 */ @RestControllerAdvice public class GlobalException2{ @ExceptionHandler public ModelAndView exceptionHandler(Exception e){ ModelAndView mv=new ModelAndView(); mv.setViewName("error"); //判断异常类型 if(e instanceof BusinessException){ BusinessException ex=(BusinessException)e; mv.addObject("msg","系统繁忙,请稍后再试......."); } //强制更换视图解析器 不跳页面!!! mv.setView(new MappingJackson2JsonView()); return mv; } }
(3) 返回异常信息和状态码
package com.xqx.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import java.util.HashMap; import java.util.Map; /** * SpingMVC提供的第三种种全局异常处理方式 * 1)@ControllerAdvice +@ExceptionHandler * 2)@RestControllerAdvice +@ExceptionHandler * @RestControllerAdvice ==@Controller +@ResponseBody 返回JSON的数据格式,绕开视图解析器 */ @RestControllerAdvice public class GlobalException2{ @ExceptionHandler public Map<String, Object> exceptionHandler(Exception e){ Map<String, Object> json=new HashMap(); //判断异常类型 if(e instanceof BusinessException){ json.put("msg","系统繁忙,请稍后再试......."); json.put("code",500); } return json; } }