前期回顾:
创建Spring Boot项目
Spring Boot项目基础配置
Spring Boot上传文件
整个实现围绕着@ControllerAdvice注解来进行的,@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute、@InitBinder使用。
import java.util.Map;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class CustomExceptionHandler {
//成功
private final static int success = 0;
//校验
private final static int invalid = 100;
@ExceptionHandler(Exception.class)
public Map<String, Object> allException(Exception e) {
log.error("捕获Exception异常", e);
Map<String, Object> map = Maps.newHashMap();
map.put("code", invalid);
map.put("msg", e.getMessage());
return map;
}
@ExceptionHandler(IllegalArgumentException.class)
public Map<String, Object> checkHandler(IllegalArgumentException e) {
log.error("出现校验错误", e);
Map<String, Object> map = Maps.newHashMap();
map.put("code", invalid);
map.put("msg", e.getMessage());
return map;
}
}
代码解释:首先我们自定义一个CustomExceptionHandler类,在此处大家可能会看到用的注解是@RestControllerAdvice,不了解的同学们可能会有点疑惑,其实@RestControllerAdvice与@ControllerAdvice注解就和@RestController和@Controller的关系一样,为了不在方法上重复定义@ResponseBody注解,所以就直接采用了@RestControllerAdvice。演示代码中可以看到定义了两个异常捕获处理,通过@ExceptionHandler()注解标明方法所针对的异常。其中,checkHandler方法所捕获的为IllegalArgumentException异常,当程序抛出IllegalArgumentException异常时,只会进入此方法进行处理,当发生其它异常时,则会进入allException方法进行处理。至于返回形式根据各位实际项目中需求可自行定义。
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Employee {
private String name;
private Department department;
}
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Department {
private String name;
private Long id;
}
定义全局数据:
import com.lei.tang.demo.domain.emp.Department;
import com.lei.tang.demo.domain.emp.Employee;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "employeeZhang")
public Employee build() {
Employee employee = new Employee();
employee.setName("张三");
Department department = new Department();
department.setId(1L);
department.setName("业务部");
employee.setDepartment(department);
return employee;
}
}
测试:
import java.util.Map;
import com.lei.tang.demo.domain.emp.Department;
import com.lei.tang.demo.domain.emp.Employee;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/global")
public class GlobalController {
@GetMapping("/modelAttribute")
public Employee modelAttribute(Model model) {
Map<String, Object> map = model.asMap();
return (Employee) map.get("employeeZhang");
}
}
代码解释:通过@RestControllerAdvice与@ModelAttribute注解搭配使用定义了一个全局数据,@ModelAttribute注解中的value值为后期我们取数据时的key,返回值为需要的值,在测试代码中我们可以看到通过Model类我们我们可以直接获取到定义的全局数据。
import com.lei.tang.demo.domain.emp.Department;
import com.lei.tang.demo.domain.emp.Employee;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalConfig {
@InitBinder(value = "emp")
public void initEmployee(WebDataBinder webDataBinder) {
webDataBinder.setFieldDefaultPrefix("emp.");
}
@InitBinder(value = "department")
public void initDepartment(WebDataBinder webDataBinder) {
webDataBinder.setFieldDefaultPrefix("department.");
}
}
测试:通过访问http://localhost:8088/global/initBinder?emp.name=张三&department.name=业务部&department.id=1
import java.util.Map;
import com.lei.tang.demo.domain.emp.Department;
import com.lei.tang.demo.domain.emp.Employee;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/global")
public class GlobalController {
@GetMapping("/initBinder")
public Employee initBinder(@ModelAttribute("emp") Employee employee, @ModelAttribute("department") Department department) {
employee.setDepartment(department);
return employee;
}
}
代码解释:定义了两个处理器,两个处理器中的webDataBinder.setFieldDefaultPrefix方法是设置请求参数映射到Bean的属性时会自动加上指定的前缀,所以可以看到测试代码中的请求路径中的所以参数都加上的对应的前缀,否则无法映射到Bean的属性上。而@InitBinder(value = “emp”)与@ModelAttribute(“emp”)和@InitBinder(value = “department”)与@ModelAttribute(“department”)形成一一对应的关系。
如有不到之处,欢迎各位留言指正,不慎感激。
更多文章:
点击跳转CSDN博客
点击跳转简书博客
公众号:代码小搬运