目录
SpringMVC相关概念
SpringMVC
是隶属于
Spring
框架的一部分,主要是用来进行
Web开发,
基于
Java
实现
MVC
模型的轻量级
Web
框架,是对Servlet进行了封装,
使用简单、开发便捷
(
相比于
Servlet),
其主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端。
之前的web程序因为是同步调用,性能慢慢的跟不上需求,所以异步调用慢慢的走到了前台,是现在比较流行的一种处理方式,前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成
json
格式进行返回,SpringMVC
主要
负责的就是
- controller如何接收请求和数据
- 如何将请求和数据转发给业务层
- 如何将响应数据转换成json发回到前端
SpringMVC如何接收请求、数据和响应结果
一次性工作
1、创建工程,设置服务器,加载工程
2、导入坐标
javax
.
servlet
-
api,spring
-
webmvc和build插件
tomcat7
-
maven
-
plugin
3、创建
web
容器启动类,加载
SpringMVC
配置,并设置
SpringMVC
请求拦截路径
4、SpringMVC核心配置类替换
web.xml(设置配置类,扫描controller
包,加载
Controller
控制器
bean
)
//web容器配置类
//AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径,即SpringMVC拦截哪些请求
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
多次工作
5、定义处理请求的控制器类
6、定义处理请求的控制器方法,并配置映射路径(
@RequestMapping
)与返回
json
数据
(
@ResponseBody
)
//定义表现层控制器bean
@Controller
public class UserController {
//设置当前方法映射路径为/save,即外部访问路径
@RequestMapping("/save")
//设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
如何让
Spring
和
SpringMVC分开加载各自的内容?使用精准范围扫描或排除扫描
- SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
- Spring控制的bean包括业务bean(Service)和功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
@Configuration
//@ComponentScan({"com.itheima.service","com.itheima.dao"})
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
请求参数
建议为不同模块设置模块名作为请求路径前置以减少命名冲突
- 当类上和方法上都添加了@RequestMapping注解,前端发送请求的时候,要和两个注解的value 值相加匹配才能访问到。
- @RequestMapping注解value属性前面加不加/都可以
1、普通参数:使用@RequestParam注解解决地址参数名与形参变量名不同的问题
2、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数,否则无法封装
3、数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数
4、集合保存普通参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
5、json数据传输参数:先开启json数据类型自动转换 @EnableWebMvc,再使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
请求数据
[
{"name":"itcast","age":15},
{"name":"itheima","age":12}
]
后台接收
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
6、日期类型参数:SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd。传递其他格式需要使用@DateTimeFormat
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2
响应
响应页面:不加
@ResponseBody
响应数据:加
@ResponseBody,
写在类上就是该类下的所有方法都有
@ReponseBody
功能
文本数据:方法的返回值为字符串,会将其作为文本内容直接响应给前端
json数据:方法的返回值为对象,会将对象转换成
JSON
响应给前端
RESTful风格及其使用
REST(
Representational State Transfer
),表现形式状态转换
,是一种软件架构风格,可以降低开发的复杂性,提高系统的可伸缩性,后期的应用也是非常广 泛,
rest
隐藏资源的访问行为,无法通过地址得知对资源是何种操作,也使书写简化,REST
中规定
GET/POST/PUT/DELETE
针对的是查询
/
新增
/
修改
/删除,根据
REST
风格对资源进行访问称为
RESTful
。
@RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
@RequestMapping("/books")
public class BookController {
// @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
异常处理
所有的异常均抛出到表现层进行处理,SpringMVC提供了异常处理器,集中的、统一的处理项目中出现的异常
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public void doException(Exception ex){
System.out.println("嘿嘿,异常你哪里跑!")
return new Result(666,null,"嘿嘿,异常你哪里跑!");
}
}
异常解决方案:
1.
先通过自定义异常,完成
BusinessException
和
SystemException
的定义
2.
将其他异常包装成自定义异常类型
//模拟业务异常,包装成自定义异常
if(id == 1){
throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
}
//模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
try{
int i = 1/0;
}catch (Exception e){
throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
}
3.
在异常处理器类中对不同的异常进行处理
//@ExceptionHandler用于设置当前处理器类对应的异常类型
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
拦截器
拦截器(
Interceptor
)是一种动态拦截方法调用的机制,在
SpringMVC
中动态拦截控制器方法
的执行,以针对
SpringMVC的访问进行增强;
拦截器中的
preHandler
方法,如果返回
true,
则代表放行,会执行原始
Controller
类中要请求的方法,如果返回
false
,则代表拦截,后面的就不会再执行了
步骤一:创建拦截器类
@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
@Override
//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
HandlerMethod hm = (HandlerMethod)handler;
System.out.println("preHandle..."+contentType);
return true;
}
@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
步骤二:配置拦截器类
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
}
}
当配置多个拦截器时,形成拦截器链,拦截器链的运行顺序参照拦截器添加顺序为准
当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
当拦截器运行中断,仅运行配置在前面的拦截器的
afterCompletion
操作