JSON是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。JSON的常用场景包括:
除了JSON,还有其他的数据传输格式,如XML等。但是由于XML格式的特点,它在Web开发中使用较少。
Jackson是一个Java库,用于将Java对象转换为JSON格式,以及将JSON格式转换为Java对象。它提供了一种简单的方式来序列化和反序列化Java对象,使得它们可以很容易地在Java应用程序和Web服务之间进行传输。
Jackson库是一个开源项目,由FasterXML开发。它是目前最流行的Java JSON库之一,被广泛应用于各种Java项目中。
优点:
容易使用,提供了高层次外观,简化常用的用例。
无需创建映射,API提供了默认的映射大部分对象序列化。
性能高,快速,低内存占用
创建干净的json
不依赖其他库
代码开源
下面是一个简单的示例:
假设有一个Person类:
- public class Person {
- private String name;
- private int age;
- @JsonIgnoreProperties({"address"}) // 忽略address属性的序列化和反序列化
- private Address address;
- // getter and setter methods...
- }
在序列化时,只有name和age属性会被序列化到JSON中:
- ObjectMapper objectMapper = new ObjectMapper();
- String json = objectMapper.writeValueAsString(person);
在反序列化时,只有name和age属性会被反序列化为Java对象:
Person person = objectMapper.readValue(json, Person.class);
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.9.3version>
- dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-coreartifactId>
- <version>2.9.3version>
- dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-annotationsartifactId>
- <version>2.9.3version>
- dependency>
- <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">
-
- <property name="supportedMediaTypes">
- <list>
- <value>text/html;charset=UTF-8value>
- <value>text/json;charset=UTF-8value>
- <value>application/json;charset=UTF-8value>
- list>
- property>
- bean>
@ResponseBody使用
@ResponseBody注解的作用是将Controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
在使用此注解之后不会再走视图解析器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
以下我会以JSON格式的不同情况来演示数据回显。
JsonController.java
- @Controller
- @RequestMapping("/stu/json")
- public class JsonController {
-
- @Autowired
- private StudentBiz stubiz;
-
- /**
- * 返回List
- * @param req
- * @param Student
- * @return
- */
- @ResponseBody
- @RequestMapping("/list")
- public List
list(HttpServletRequest req, Student Student){ - PageBean pageBean = new PageBean();
- pageBean.setRequest(req);
- List
lst = this.stubiz.selectBySnamePager(Student, pageBean); - return lst;
- }
-
- /**
- * 返回T
- * @param req
- * @param Student
- * @return
- */
- @ResponseBody
- @RequestMapping("/load")
- public Student load(HttpServletRequest req, Student Student){
- if(Student.getSid() != null){
- List
lst = this.stubiz.selectBySnamePager(Student, null); - return lst.get(0);
- }
- return null;
- }
-
-
- /**
- * 返回List
- * @param req
- * @param Student
- * @return
- */
- @ResponseBody
- @RequestMapping("/mapList")
- public List
- PageBean pageBean = new PageBean();
- pageBean.setRequest(req);
- List
- return lst;
- }
-
- /**
- * 返回Map
- * @param req
- * @param Student
- * @return
- */
- @ResponseBody
- @RequestMapping("/mapLoad")
- public Map mapLoad(HttpServletRequest req, Student Student){
- if(Student.getSid() != null){
- List
- return lst.get(0);
- }
- return null;
- }
-
-
- @ResponseBody
- @RequestMapping("/all")
- public Map all(HttpServletRequest req, Student Student){
- PageBean pageBean = new PageBean();
- pageBean.setRequest(req);
- List
lst = this.stubiz.selectBySnamePager(Student, pageBean); - Map map = new HashMap();
- map.put("lst",lst);
- map.put("pageBean",pageBean);
- return map;
- }
-
- @ResponseBody
- @RequestMapping("/jsonStr")
- public String jsonStr(HttpServletRequest req, Student Student){
- return "clzEdit";
- }
-
- }
通过以上的案例我们可以看到返回T和List
小贴士:
@Controller注解用于标识一个类是Spring MVC中的控制器,即处理用户请求并返回响应的组件。
@ResponseBody注解用于将方法返回的对象转换为JSON格式的字符串,并将其作为HTTP响应体发送给客户端。
因此,@RestController注解合集的含义是:将一个类标记为Spring MVC控制器,并使用@ResponseBody注解将方法返回的对象转换为JSON格式的字符串,以便于在浏览器或其他客户端中进行访问。
在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护 ,全局异常处理是指在应用程序中对所有异常进行捕获和处理,而不是仅仅对特定的异常进行处理。
以下是一些原因说明为什么要全局异常处理:
综上所述,全局异常处理可以使应用程序更加健壮、一致、易于维护和安全,同时提供更好的用户体验。
面试题:运行时异常和编译时异常的区别?
- 编译时异常(Checked Exception): 编译时异常是在编译阶段被检查出来的异常,必须进行处理,否则编译器会报错。常见的编译时异常有IOException、SQLException等。处理方式可以使用try-catch语句块来捕获和处理这些异常。
- 运行时异常(Runtime Exception): 运行时异常是在程序运行期间抛出的异常,如果不进行处理,程序会崩溃。常见的运行时异常有NullPointerException、ArrayIndexOutOfBoundsException等。这些异常通常是由程序逻辑错误引起的,因此无法在编译时进行检测。
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
具体来说,异常处理的思路包括以下几个方面:

SpringMVC中的异常处理方式有三种:
SpringMVC中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口。
spring-mvc.xml
- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
-
- <property name="defaultErrorView" value="error"/>
-
- <property name="exceptionAttribute" value="ex"/>
-
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.RuntimeException">errorprop>
- props>
-
- property>
- bean>
error.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>系统繁忙title>
- head>
- <body>
- ${ex}<br>
- <img src="${pageContext.request.contextPath }/static/1.jpg" style="height: 1000px;width: 1550px;">
-
- body>
- html>
页面跳转由SpringMVC来接管了,所以此处的定义默认的异常处理页面都应该配置成逻辑视图名。
我们没有配置这段代码之前,以下的页面是我们不想看到的,看看配置后是怎么样的吧?

配置异常处理:

创建一个名为exception的包将我们的GlobalException类放入其中。
GlobalException.java
- 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类放入其中。
GlobalExceptionHandler.java
- @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;
- }
- }
1.通过instanceof判断异常类型
2.通过设置mv.setView(new MappingJackson2JsonView())方式返回JSON数据
这时候我们来访问以下http://localhost:8080/liwenzyssm/stu/json/jsonStr
因为异常处理会根据我们的异常问题进行判断map保存输出到前端,所以在JSP页面上用EL表达式捕捉msg信息就可以知道问题是什么更为直观。

GlobalExceptionResolver.java
- @ControllerAdvice
- public class GlobalExceptionResolver {
-
-
- // 返回错误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格式输出在页面上。
这时候我们来访问以下 http://localhost:8080/wenhaozyssm/stu/json/jsonStr
通过我刚刚的解释想必大家对异常处理有了一定的理解,但是大家有没有发现,异常处理类中反复的需要定义Map,随后.put添加数据,我们能否对以上代码进行优化呢?能!!下面请欣赏小编所需的R工具类。
- public class R extends HashMap {
- public R data(String key, Object value) {
- this.put(key, value);
- return this;
- }
-
- public static R ok(int code, String msg) {
- R r = new R();
- r.data("success", true).data("code", code).data("msg", msg);
- return r;
- }
-
- public static R error(int code, String msg) {
- R r = new R();
- r.data("success", false).data("code", code).data("msg", msg);
- return r;
- }
-
- public static R ok(int code, String msg,Object data) {
- R r = new R();
- r.data("success", true).data("code", code).data("msg", msg).data("data", data);
- return r;
- }
-
- public static R ok(int code, String msg, long count, Object data) {
- R r = new R();
- r.data("success", true).data("code", code).data("msg", msg).data("count", count).data("data", data);
- return r;
- }
- }
GlobalExceptionResolver.java
- @ControllerAdvice
- public class GlobalExceptionResolver {
-
- // 响应封装类
- @ResponseBody
- @ExceptionHandler
- public Map handler(Exception e){
-
- if (e instanceof GlobalException){
- GlobalException globalException = (GlobalException) e;
- return R.ok(500,"全局异常....",globalException.getMessage());
- }else if (e instanceof RuntimeException){
- RuntimeException runtimeException = (RuntimeException) e;
- return R.ok(500,"运行时异常....",runtimeException.getMessage());
- }else {
- return R.ok(500,"其他异常....",e.getMessage());
- }
- }
- }
这时候我们来访问以下 http://localhost:8080/wenhaozyssm/stu/jsonsonStr
