文章目录
SpringMVC框架
MVC三层架构
概述:MVC(Model View Controller),一种用于设计创建Web应用程序表现层的模式。
作用:分离数据的存储和数据的展示
- Model(模型):数据模型,用于封装数据。
- View(视图):页面视图,用于展示数据jsp、html。
- Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑。
- Servlet
- SpringMVC
SpringMVC技术架构
DispatcherServlet:前端控制器,是整体流程控制的中心,由其调用其它组件处理用户的请求,有效的降低了组件间的耦合性。
HandlerMapping:处理器映射器,负责根据用户请求找到对应具体的Handler处理器。
Handler:处理器,业务处理的核心类,通常由开发者编写,描述具体的业务。
HandlerAdapter:处理器适配器,通过它对处理器进行执行。
ViewResolver:视图解析器,将处理结果生成View视图。
View:视图,最终产出结果,常用视图如jsp、html 。
SpringMVC简介
概述:
- 基于MVC设计模型的请求驱动类型的轻量级Web框架。
- 通过一套注解,让一个简单的 Java 类成为处理器代替以前的Servlet。
- 支持RESTful编程风格的请求。
使用步骤:
- 创建Web工程(Maven结构)。
- 设置tomcat服务器,加载web工程(可选)。
- 导入坐标(SpringMVC+Servlet)。
- 定义处理请求的类(UserController)。
- 设置请求映射(配置映射关系)。
- 将SpringMVC设定加载到Tomcat容器中
<!--设置tomcat服务器,加载web工程-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 导入springmvc的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--添加json数据转换相关坐标-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
//定义表现层控制器bean
@Controller
public class UserController {
//设置映射路径为/save,即外部访问路径
@RequestMapping("/save")
//设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
}
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.lxl.controller","com.lxl.config")
@EnableWebMvc
//@EnableWebMvc注解功能强大,该注解整合了多个功能,如json数据进行自动类型转换
public class SpringMvcConfig {
}
@Configuration //SpringMvc副配置类,用于配置静态资源、拦截器等...
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
}
MVC相关注解
名称:@Controller
类型:类注解
位置:SpringMVC控制器类定义上方
作用:设定SpringMVC的核心控制器bean,不可@Component替代
名称:@EnableWebMvc
类型:配置类注解
位置:SpringMVC配置类定义上方
作用:开启SpringMVC多项辅助功能,如自动解析json格式
名称:@RequestMapping
类型:方法注解、类注解
位置:SpringMVC控制器方法、类定义上方
作用:
- 设置当前控制器方法请求访问路径,save前斜杠可以省略;
- 设置在类上,统一设置当前控制器方法请求访问路径前缀
名称:@ResponseBody
类型:方法注解、类注解
位置:SpringMVC控制器方法、类定义上方
作用:设置当前控制器方法响应内容为当前返回值,无需解析
名称:@RequestParam
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:绑定请求参数与处理器方法形参间的关系
名称:@RequestBody
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
名称:@DateTimeFormat
类型:形参注解
位置:SpringMVC控制器方法形参前面
作用:设定日期时间型数据格式,默认是yyyy/MM/dd
名称:@PathVariable
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应
名称:@RestController
类型:类注解
位置:基于SpringMVC的RESTful开发控制器类定义上方
作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能
名称:@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
类型:方法注解
位置:基于SpringMVC的RESTful开发控制器方法定义上方
作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求
MVC请求格式
GET/POST-普通参数
//普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(@RequestParam("name") String username ,int age){
System.out.println("普通参数传递 name ==> "+username);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
POST请求乱码
//为web容器添加过滤器并指定字符集,Spring-web包中提供了专用的字符过滤器
public class ServletConfigInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
// 配字符编码过滤器,重写方法
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
POJO格式参数
//POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
//嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
public class User {
private String name;
private int age;
private Address address;
}
public class Address {
private String province;
private String city;
}
数组/集合格式参数
//数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] hobby){
System.out.println("数组参数传递==> "+ Arrays.toString(hobby));
return "{'module':'array param'}";
}
//集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个
//@RequestParam绑定参数关系
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> hobby){
System.out.println("集合参数传递==> "+ hobby);
return "{'module':'list param'}";
}
请求体-JSON格式
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("user ==> "+user);
return "{'module':'pojo for json param'}";
}
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list ==> "+list);
return "{'module':'list pojo for json param'}";
}
参数日期格式处理
@RequestMapping("/dateParam")
@ResponseBody
public String dateParam(Date date,@DateTimeFormat(pattern = "yyyy-MM-dd") Date date_){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date(yyyy-MM-dd) ==> "+date_);
return "{'module':'data param'}";
}
@RequestBody与@RequestParam区别
区别:
- @RequestParam用于接收url地址传参,表单传参[application/x-www-form-urlencoded]
- 传递的参数格式是:键=值&键=值。
- 底层使用是getParameter(“键”)。
- @RequestBody用于接收json数据[application/json]
- 数据在请求体中,不能用于GET方法,只能出现一次,因为每次请求只有一个请求体。
- 不能获取键值对的数据,底层使用getReader()方法。
应用:
- 后期开发中,发送json格式数据为主,@RequestBody应用较广。
- 如果发送非json格式数据,选用@RequestParam接收请求参数。
MVC响应格式
请求转发与重定向
@RequestMapping("/toPage")
public String toPage(){
return "page.jsp";
}
//方法的上面无需@ResponseBody注解
//转发 (默认)-forward:地址
//重定向-redirect:地址
响应文本数据
//早期写法
response.setContentType("text/plain;charset=utf-8");
response.getWriter().write("response text!");
//SpringMVC写法
@RequestMapping("/toText")
@ResponseBody
public String toText(){
return "response text";
}
响应JSON格式
//早期做法
List<Brand> brands = service.selectAll();
String jsonString = JSON.toJSONString(brands);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
//SpringMVC写法
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
User user = new User();
user.setName("赵云");
user.setAge(41);
return user;
}
RESTful风格
传统请求:访问地址各不相同需要在请求体或地址栏上携带参数,通过?分隔地址栏和参数。
RESTful请求:访问地址是一样的参数是通过/分隔的,如果有多个参数,使用多个/。
RESTful其中的两个特点:
- 每一个URI代表1种资源
- 客户端使用GET、POST、PUT、DELETE四个表示操作方式的动词对服务端资源进行操作
- GET用来获取资源
- POST用来新建资源
- PUT用来更新资源
- DELETE用来删除资源
@Controller
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
public Book findBookById(@PathVariable int id) {
return bookService.findBookById(id);
}
@RequestMapping(method = RequestMethod.GET)
public boolean addBook(@RequestBody Book book) {
return bookService.addBook(book);
}
}
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/{id}")
public Book findBookById(@PathVariable int id) {
return bookService.findBookById(id);
}
@PostMapping
public boolean addBook(@RequestBody Book book) {
return bookService.addBook(book);
}
}
SpringMvc常用注解
- **@RequestMapping:**用于处理所有请求类型 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
- @GetMapping,处理get请求类型。
- @PutMapping,处理get请求类型。
- @DeleteMapping,处理get请求类型。
- @PostMapping,处理get请求类型。
- **@RequestBody:**注解实现接收http请求的json数据,将json转换为java对象。
- **@ResponseBody:**注解实现将conreoller方法返回对象转化为json对象响应给客户。
- **@PathVariable:**用户从url路径上获取指定参数,标注在参数前 @PathVariabel(“要获取的参数名”)。
- @RequestParam: 标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:
- value:默认属性,用于指定前端传入的参数名称。
- required:用于指定此参数是否必传。
- defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值。
- **@RequestAttribute:**注解的参数在项目里是自己解析出来的,并不是前端传递的。具体一点,在项目里的拦截器里会对Token信息进行解析,解析出来的参数重新放在请求里(用httpServletRequest.setAttribute(name, value)),后边接口接收参数时就用这个注解。
- **@ControllerAdvice:**标注在一个类上,表示该类是一个全局异常处理的类。
- **@ExceptionHandler(Exception.class):**标注在异常处理类中的方法上,表示该方法可以处理的异常类型。