@ControllerAdvice 是什么
在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。参考:@ControllerAdvice 文档
常见用法
一般项目都会定义一个类似于
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ControllerAdvice
public class GlobalExceptionHandler {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(Exception e, HttpServletRequest request) throws Exception {
logger.info("请求地址:" + request.getRequestURL());
ModelAndView mav = new ModelAndView();
logger.error("异常信息:",e);
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
}
全局异常处理,统一处理controller中发生的异常
@ExceptionHandler(value = Exception.class)中的value异常类型可以自定义,比如:
1
2
3
4
5
6
7
8
9
10
11
12
public class MyException extends RuntimeException {
public MyException(String code, String msg) {
this.code = code;
this.msg = msg;
}
private String code;
private String msg;
// getter & setter
}
然后修改value如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@ControllerAdvice
public class MyExceptionHandler {
/**
* 拦截捕捉自定义异常 MyException.class
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = MyException.class)
public Map myErrorHandler(MyException ex) {
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
}
测试的话,编写好@ControllerAdvice类后,在controller中throw一个Exception
1
2
3
4
5
6
7
8
9
@RestController
public class TestController {
@RequestMapping("/test")
public String test(){
throw new MyException(10000, "system error.");
}
}
访问该controller就会返回自定义的异常json信息
注意
@ControllerAdvice可以通过在方法上增加@ResponseBody注解放回json,也可以直接使用注解@RestControllerAdvice免去注解@ResponseBody
以上至介绍了统一处理异常机制@ExceptionHandler,在@ControllerAdvice中还可以
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
**
* 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
* @param binder
*/
@InitBinder
public void initBinder(WebDataBinder binder) {}
/**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
* @param model
*/
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("author", "Magical Sam");
}
数据结构和算法的关系
数据结构是偏系统底层的概念,而算法是偏应用层的概念,算法操作数据结构
常见的数据结构链表、数组
链表:不连续的内存空间,通过指针连接元素
数组:连续的内存空间,元素有序依次存储
由于数组是有序的,所以数组查询快,增删慢(增加、删除节点需要移动其它元素,复杂度高)
链表由于指针的特性增加删除快而简单,查询慢(由于无序,查询需要遍历元素)
spring boot中如何自定义过滤器Filter
自定义过滤器,Object implements Filter的类还是要写,只是在spring boot中去掉web.xml后的写法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class WebConfiguration {
@Bean
public FilterRegistrationBean filterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SecurityFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("MyFilter");
registration.setOrder(1);
return registration;
}
}
回顾一下老写法,在web.xml中配置自定义过滤器如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.nobt.MyFilter</filter-class>
<init-param>
<param-name>EXCEPTION_URI</param-name>
<param-value>login.html,*.js</param-value>
</init-param>
<init-param>
<param-name>ERR_URL</param-name>
<param-value>login.html</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
总结新用法:
- 实现
javax.servlet.Filter接口,实现Filter方法 - 添加
@Configuration注解,将自定义Filter加入过滤链
缺陷:
-
队列(mq)、缓存(redis)、搜索引擎(es)、分布式(spring cloud)的具体实现
队列只是简单的了解到比如点对点queue、群发topic
redis了解程度仅限于常用crud,其中细节的多数据类型、持久化、结合实际业务用redis达到高效率的做法等了解有限
搜索引擎只简单看过lucene
springcloud只简单的动手过如eureka、config、hystrix、feign、zuul,将服务提供者和服务消费者分模块建立,并分开部署启动后注册到eureka,通过feign远程调用,config动态拉取远端github配置并生效,hystrix达到服务降级/处理服务异常超时等问题,zuul控制微服务网关统一管理
谈谈项目分模块的理解:
单体的项目也可以通过meven分模块建立,分模块后的模块引用就类似于单独开发出来的jar包被引用,最终达到的效果与传统项目(所有服务、工具都在一个项目)效果一致,实际上也是统一部署,只是涉及到jar包的引用,通过maven最终打包出来一个jar/war包供启动,但是当项目复杂时可降低复杂度,更清晰的开发与维护,像spring cloud/dubbo微服务概念中,比如一个服务提供者和服务消费者在代码层面就是分模块,并部署也是分开部署的,他们之间的调用通过注册中心维护关系,并远程调用
-
springboot中一些细节的配置方式,没经验/对springboot的不熟悉可能导致愚蠢的做法