注解方式启动MVC
@Configuration
@ComponentScan(basePackages = {"com.mayikt.controller","com.mayikt.service"})
//@EnableWebMvc
@EnableAsync
public class SpringMvcConfig extends WebMvcConfigurationSupport {
//@EnableWebMvc 等于开启SpringMVC注解方式
//@Configuration xml
// @ComponentScan("com.mayikt.controller") mvc 扫包范围
//DispatcherServlet
// 百度搜索 SpringMVC注解方式(⊙o⊙)…
//extends WebMvcConfigurerAdapter 这是错误的。。
//@EnableWebMvc 底层会帮助我们注入WebMvcConfigurationSupport这类 覆盖我们自定义配置类
@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
// 1.需要前缀
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
// 2.需要后缀
internalResourceViewResolver.setPrefix("/WEB-INF/view/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
// 1.手动注入拦截器到Spring中
@Bean
public TokenInterceptor tokenInterceptor() {
return new TokenInterceptor();
}
// 2.添加拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor()).addPathPatterns("/**");// 拦截所有的请求
}
// 配置springmvc相关一些信息WebMvcConfigurationSupport web视图相关内容
}
public class WebInitializer implements WebApplicationInitializer {
public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
// 1.启动SpringMVC 容器 类注入到Spring中
AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();// 启动SpringMVC Web
// 2.注入我们的springmvc 的配置文件
app.register(SpringMvcConfig.class);
// 3. 将我们的DispatcherServlet 注入到 serlvet容器中
ServletRegistration.Dynamic dynamic =
servletContext.addServlet("dispatcher", new DispatcherServlet(app));
// 4.填写url路径映射
dynamic.addMapping("/");
dynamic.setLoadOnStartup(1);// 优先级最高表示 最早被加载
dynamic.setAsyncSupported(true); // 开启SpringMVC异步
}
// 基本配置已经ok呢? web.xml ? 使用WebApplicationInitializer 替代web.xml
}
拦截器与过滤器
- 拦截器和过滤器都是基于Aop实现,能够对请求执行之前和之后实现拦截。
- 过滤器是基于Servlet容器实现,对Web请求之前和之后实现拦截
- 拦截器不需要依赖于Servlet、不仅可以实现Web请求还有其他方法拦截等。
应用场景
拦截器:权限控制、日志打印、参数验证 、会话。
过滤器应用场景:编码转换、跨域解决、xss攻击
自定义拦截器
- preHandle在业务处理器处理请求之前被调用;
- postHandle在业务处理器处理请求执行完成后,生成视图之前执行;
- afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 afterCompletion()执行完成后开始渲染页面
public class TokenInterceptor implements HandlerInterceptor {
/**
* 请求方法前置拦截,如果返回true 表示会执行到目标方法(请求方法) 如果返回false的情况下 则不会执行目标方法。
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
System.out.println(">>>>token<<<<:" + token);
if (StringUtils.isEmpty(token)) {
response.setStatus(500);
response.getWriter().print(" token is null");
return false;
}
// 执行我们的请求方法
return true;
}
/**
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("<<<postHandle>>>>");
// 请求之后执行。
}
/**
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(">>>afterCompletion<<<");
// 请求之后执行。 周六晚上源码解析的
}
}
注意:使用拦截器一定要关闭EnableWebMvc 否则拦截器不会生效。
异步
使用异步Callable 带返回结果
@RequestMapping(value = "/asyncPay")
@ResponseBody
public Callable<String> asyncPay() {
System.out.println(">>>1.开始调用pay<<<<<<< ThradName:" + Thread.currentThread().getName());
Callable callable= new Callable<String>() {
public String call() throws Exception {
payServie.pay();
return "success";
}
};
System.out.println(">>>3.结束调用pay<<<<<<< ThradName:" + Thread.currentThread().getName());
return callable;
}