本文最后更新于49 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1、简介
SpringMVC技术与Servlet技术功能等同,均属于web层开发技术。用来替换Servlet。
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架。
- 优点
- 使用简单,开发便捷(相比于Servlet)
- 灵活性强
2、SpringMVC入门案例
//jar导入
<!--1.导入坐标springmvc与servLet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
(2)bean加载控制
因为功能不同,如何避免Spring错误的加载到SpringMVC的bean?
—>加载Spring控制的bean的时候排除掉SpringMVC控制的bean。
1)具体措施
- SpringMVC相关bean加载控制
- SpringMVC加载的bean对应的包均在com.itheima.controller包内
- Spring相关bean加载控制
- 方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean;
- 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
- 方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中
//常用:web配置类简化开发,仅设置配置类类名即可
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
(3)设置请求映射路径
团队多人开发,每人设置不同的请求路径,冲突问题如何解决?
—>设置模块名作为请求路径前缀
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
//请求路径映射
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
//请求路径映射
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
(5)Json传参(常用)
(6)日期型参数传递
3、响应
//对SpringMVC来说,跳转页面很简单
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
//响应文本数据
//返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
//@ResponseBody
//方法注解
//位置:SpringMVc控制器方法定义上方
//作用一:设置当前控制器方法响应内容为当前返回值,无需解析
//作用二:设置当前控制器返回值作为响应体
4、REST
REST(Representational StateTransfer),表现形式状态转换
传统风格资源描述形式:
http://localhost/user/getById?id=1
http://localhost/user/saveUser
REST风格描述形式:
http://localhost/user/1
http://localhost/user
根据REST风格对资源进行访问称为RESTful
优点:
隐藏资源的访问行为,无法通过地址得知对资源是何种操作
书写简化
上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts等
(1)入门案例
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为PUT,表示REST风格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
//@PathVariable:允许你轻松地从URL中提取这些值,并将它们作为方法的参数。
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users",method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
- 区别
- @RequestParam用于接收url地址传参或表单传参;
- @RequestBody用于接收json数据
- @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
- 应用
- 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
- 如果发送非json格式数据,选用@RequestParam接收请求参数
- 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
(2)简化
//@Controller
//@ResponseBody配置在类上可以简化配置,表示设置当前每个方法的返回值都作为响应体
//@ResponseBody
@RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
@RequestMapping("/books")
//@RequestMapping( method = RequestMethod.POST)
@PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
//@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
//@RequestMapping(method = RequestMethod.PUT)
@PutMapping //使用@PutMapping简化Put请求方法对应的映射配置
//@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
@GetMapping("/{id}") //使用@GetMapping简化GET请求方法对应的映射配置
//@RequestMapping(method = RequestMethod.GET)
@GetMapping //使用@GetMapping简化GET请求方法对应的映射配置
5、SSM整合
(1)表现层数据封装
前端接收数据格式——封装data
前后端约定协议:
设置统一数据返回结果类
public class Result{
private Object data;
private Integer code;
private String msg;
}
(2)异常处理器
- 出现异常现象的常见位置与常见诱因如下:
- 框架内部抛出的异常:因使用不合规导致;
- 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时);
- 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等);
- 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常);
- 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)。
- 各个层级均出现异常,异常处理代码书写在哪一层
- 所有的异常均抛到表现层进行处理
- AOP处理
//整个类
@RestControllerAdvice
public class ProjectExceptionAdvice {
//作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
System.out.println("捕获到异常");
return new Result(404,"服务器异常");
}
}
(3)项目异常处理方案
- 项目异常分类
- 业务异常(BusinessException)
- 规范的用户行为产生的异常
- 不规范的用户行为操作产生的异常
- 系统异常(SystemException)
- 项目运行过程中可预计且无法避免的异常
- 其他异常(Exception)
- 编程人员未预期到的异常
- 业务异常(BusinessException)
(4)拦截器(Interceptor)
- 拦截器是一种动态拦截方法调用的机制
- 作用:
- 在指定的方法调用前后执行预先设定后的的代码
- 阻止原始方法的执行
- 拦截器与过滤器区别
- 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVc技术;
- 拦截内容不同:Filter对所有访问进行 增强,Interceptor仅针对SpringMvc的访问进行增强
- 拦截器执行流程:
1)拦截器参数
2)拦截器链配置