学习资料:
常用MYSQL命令:http://t.csdn.cn/zshCP
学习要求什么是springmvc
springmvc是一种基于java实现MVC模型的轻量级web框架
比servlet更便捷
MVC模式:后端服务器
*|-----------------------------------------|--------------------------------------------------|
| controller ||
| view(页面) * HTML * CSS * VUE * ElementUI | model (最终生成的model对象是一个java对象,不能直接返回页面,要使用json格式) |
| service ||
| dao ||
springmvc基本使用步骤
- 创建web工程(maven结构)
- 设置tomcat服务器,加载web工程(tomcat插件)
- 导入坐标(SpringMVC+Servlet)
- 定义处理请求的功能类(UserController)
- 设置请求映射 (配置映射关系)
- 将SpringMVC设定加载到Tomcat容器中
启动服务器初始化过程
- 服务器启动,执行ServletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建了WebApplicationContext对象
- 加载SpringMvcConfig
- 执行@ComponentScan,加载对应的bean
- 加载UserController,每个@RequestMapping的名称对应一个具体的方法
- 执行getServletMappings方法,定义所有的请求都通过SpringMVC
- 简而言之:
- 1、把springmvc配置加载到tomcat容器中
- 2、把所有请求拦截给springmvc处理
单次请求过程
- 发送请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
- 解析请求路径/save
- 由/save匹配执行对应的方法save()
- 执行save()
- 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
Springmvc的bean扫描范围
- 因为功能不同,如何避免spring错误地加载到SpringMVC的bean?
- springmvc加载的bean均在com.itheima.controller包内
- 所以要修改spring的bean扫描范围:
方式一:把加载bean的扫描范围设定为com.itheima,再排除掉controller包内的bean
java@Configuration @ComponentScan( value="com.study",//扫描该包 excludeFilters=@ComponentScan.Filter( type= FilterType.ANNOTATION, //按注解排除 classes= Controller.class//不扫描有@Controller注解的包 ) ) public class SpringConfig { }
方式二:直接设定为更具体的包,如com.itheima.service,com.itheima.dao。。。
在springmvc项目中,以使用方式二为主
请求(解决传参的问题)
请求映射路径(@RequestMapping)
该代码具有一般性
*
javapackage com.study.config; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.Filter; public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[0]; } protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } //乱码处理 @Override protected Filter[] getServletFilters() { //为web容器添加过滤器并指定字符集 CharacterEncodingFilter filter=new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); return new Filter[]{};//数组的形式 } }
1、五种数据类型的传参(@RequestParam)
```java package com.study.controller; import com.study.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.util.Arrays; import java.util.List; @Controller public class UserController { //普通参数,当请求参数名与形参名不同时,使用RequestParam注解 @RequestMapping("/commonParam") @ResponseBody public String commonParam(@RequestParam("name")String userName){ System.out.println("普通参数传递,userName:"+userName); return "{'module':'common Param'}"; } //POJO参数 @RequestMapping("/pojoParam") @ResponseBody public String pojoParam(User user){ System.out.println("pojo参数传递,user:"+user); return "{'module':'pojo Param'}"; } //嵌套POJO参数 @RequestMapping("/pojoContainPojoParam") @ResponseBody public String pojoContainPojoParam(User user){ System.out.println("pojo嵌套参数传递,user:"+user); return "{'module':'pojo contain Param'}"; } //数组参数 @RequestMapping("/arrayParam") @ResponseBody public String arrayParam(String[] likes){ System.out.println("数组参数传递,likes:"+ Arrays.toString(likes)); return "{'module':'array Param'}"; } //集合参数 @RequestMapping("/listParam") @ResponseBody public String listParam(@RequestParam List<String> likes){ System.out.println("集合参数传递,likes:"+ likes); return "{'module':'list Param'}"; } } ```
- 简而言之,url传递参数时,如果名称不对应,使用@RequestParam注解
2、json数据传递参数(@RequestBody和@RequestParam)
(1)导入坐标
XML<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.10</version> </dependency>
(2)在核心注解类中加注解,开启自动转换json数据的支持
*
java@EnableWebMvc public class SpringMvcConfig { }
(3)注意postman里的4处
(4)添加@RequestBody注解
java//集合参数:json格式 @RequestMapping("/listParamForJson") @ResponseBody public String listParamForJson(@RequestBody List<String> likes){ System.out.println("list common(json)参数传递,list:"+ likes); return "{'module':'list Param for json param'}"; } //POJO参数:json格式 @RequestMapping("/pojoParamForJson") @ResponseBody public String pojoParamForJson(@RequestBody User user){ System.out.println("pojo(json)参数传递,user:"+ user); return "{'module':'pojo for json param'}"; } //集合参数:json格式 @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'}"; }
- 发送json数据,用注解@RequestBody
- 发送非json数据,用注解@RequestParam接收参数
3、日期型参数传递(@DateTimeFormat)
根据不同的日期格式设置不同的接收格式
java//日期参数 @RequestMapping("/dataParam") @ResponseBody public String dataParam(Date date, @DateTimeFormat(pattern="yyyy-MM-dd") Date date1, @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){ System.out.println("参数传递,date:"+ date);//2088/08/08 System.out.println("参数传递,date1(yyyy-MM-dd):"+ date1);//2088-08-08 System.out.println("参数传递,date1(yyyy/MM/dd HH:mm:ss):"+ date2);//2088/08/08 8:08:08 return "{'module':'date param'}"; }
注解@DateTimeFormat用于设定接收的日期格式
响应(@ResponseBody)
1、响应页面
```java @RequestMapping("/toPage") public String toPage(){ return "page.jsp"; } ```
2、响应json数据(对象转json)
```java @RequestMapping("/toJsonPOJO") @ResponseBody //把user对象转成json数据返回 public User toJsonPOJO(){ User user=new User(); user.setName("itcast"); user.setAge(15); return user; } ```
3、响应json数据(对象集合转json数组)
```java @RequestMapping("/toJsonList") @ResponseBody public List<User> toJsonList(){ System.out.println("返回json集合数据"); User user1=new User(); user1.setName("itcast"); user1.setAge(15); User user2=new User(); user2.setName("黑马"); user2.setAge(12); List<User> userList=new ArrayList<>(); userList.add(user1); userList.add(user2); return userList; } ```
- 类型转换器(HttpMessageConverter)
REST风格
Representational State Transfer,表现层资源状态转移
简而言之,REST风格就是访问网络资源的格式
约定可以打破,所以叫REST风格,而不是REST规范
模块名称通常用复数
使用
- 1、设定http请求动作
- 2、设定请求参数路径变量
- 是
三个接收参数的注解区别:
- (1)@RequestParam用于接收url地址传参或表单传参
- (2)@RequestBody用于接收json数据
- (3)@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
REST风格简化开发
```java //简化前 @Controller public class UserController { @RequestMapping(value="/users",method=RequestMethod.POST) @ResponseBody public String save(){ System.out.println("user save..."); return "{'module':'user save'}"; } @RequestMapping(value="/users/{id}",method=RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable Integer id){//从路径处传过来的变量 System.out.println("user delete..."+id); return "{'module':'user delete'}"; } @RequestMapping(value="/users",method=RequestMethod.PUT) @ResponseBody public String update(@RequestBody User user){ System.out.println("user update..."+user); return "{'module':'user update'}"; } @RequestMapping(value="/users/{id}",method=RequestMethod.GET) @ResponseBody public String getById(@PathVariable Integer id){ System.out.println("user getById..."+id); return "{'module':'user getById'}"; } @RequestMapping(value = "/users",method = RequestMethod.GET) @ResponseBody public String getAll(){ System.out.println("user getAll..."); return "{'module':'user getAll'}"; } } //简化后 @RestController @RequestMapping("/users") public class UserController { @PostMapping public String save(){ System.out.println("user save..."); return "{'module':'user save'}"; } @DeleteMapping("/{id}") public String delete(@PathVariable Integer id){ System.out.println("user delete..."+id); return "{'module':'user delete'}"; } @PutMapping public String update(@RequestBody User user){ System.out.println("user update..."+user); return "{'module':'user update'}"; } @GetMapping("/{id}") public String getById(@PathVariable Integer id){ System.out.println("user getById..."+id); return "{'module':'user getById'}"; } @GetMapping public String getAll(){ System.out.println("user getAll..."); return "{'module':'user getAll'}"; } } ```
基于RESTful页面数据交互
- 1、做后台功能,开发接口并调通接口
- 2、做页面异步调用,确认功能正常可以访问
- 3、完成页面数据展示
- 4、放行静态资源的访问
SSM整合(Spring,MyBatis,SpringMVC)
- 详见具体项目代码
- Spring整合MyBatis的结构
|------------------------------------------------------------------------|
| 配置(config) * SpringConfig * JDBCConfig、jdbc.properties * MyBatisConfig |
| 表现层(controller) * BookController * Result * Code |
| 模型(domain) * Book |
| 数据层标准开发(dao) * BookDao |
| 业务层标准开发(service) * BookService * BookServiceImpl |
| 测试接口(test/service) * BookServiceTest |
- 异常处理
- 项目异常:
- 1、业务异常(BusinessException)
- 发送对应消息传递给用户,提醒规范操作
- 2、系统异常(SystemException)
- 发送固定消息传递给用户,安抚用户
- 3、其他异常(Exception)
- 发送固定消息传递给用户,安抚用户
- 项目异常处理
1、自定义项目系统级异常、业务级异常......
*
html//自定义项目系统级异常 axios.get("/books").then((res)=>{});//查询 axios.post("/books",this.formData).then((res)=>{});//添加 axios.delete("/books"+row.id).then((res)=>{});//删除 axios.put("/books",this.formData).then((res)=>{});//修改 axios.get("/books"+row.id).then((res)=>{});//查询
2、自定义异常编码(类似404,500的存在)
3、触发自定义异常
拦截器(Interceptor)
- 是一种动态拦截方法调用的机制
- 拦截器和过滤器的区别:
- 1、Filter属于Servlet技术,Interceptor属于SpringMVC技术
- 2、Filter对所有访问进行增强,Interceptor仅对SpringMVC的访问进行增强
使用步骤:
- 1、声明拦截器的bean,并实现HandlerInterceptor接口
- 2、定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法
- 3、添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
拦截器参数:
1、前置处理
javapublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String contentType=request.getHeader("Content-Type"); System.out.println("preHandle..."+contentType); return true; }
- 参数:
- request:请求对象
- response:响应对象
- handler:被调用的处理器对象
- 返回值: false,被拦截的处理器将不执行
2、后置处理
javapublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle..."); }
- modelAndView: 读取并调整返回结果对应的数据和页面信息
3、完成后处理
javapublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion..."); }
- ex:处理处理器执行过程中出现的异常情况
多拦截器执行顺序(了解即可,通常一个拦截器就够用了)
- 配置的多个拦截器形成拦截器链
- 拦截器链的运行顺序以拦截器添加顺序为准