目录
1、添加依赖(spring-webmvc和javax.servlet-api)
3、定义表现层控制器UserController并且定义为bean
[4、配置web容器配置类(方式一 || 方式二)](#4、配置web容器配置类(方式一 || 方式二))
如何将他们分开定义,放在不同的容器里面(SpringConfig和SpringMVCConfig)
[一个案例 (books) 存在的问题 ???](#一个案例 (books) 存在的问题 ???)
SpringMVC框架
Spring MVC 是一种基于 Java 的 Web 应用程序框架,它是 Spring 框架的一部分,用于简化开发基于 Web 的应用程序。Spring MVC 就像是一个网站的建筑队长,它帮助开发者把网站的不同部分组织起来,让整个网站看起来更有条理。它把网站分成了三个部分:一个负责管理数据的部分(模型),一个负责展示页面的部分(视图),还有一个负责控制页面流程的部分(控制器)。
关于postman的使用介绍
新手如何使用postman(新手使用,简单明了)_postman使用教程-CSDN博客
SpringMVC入门案例
(SpringMVCConfig -> ServletContainersInitConfig > UserController)
1、添加依赖(spring-webmvc和javax.servlet-api)
2、设置配置类文件SpringMVCConfig
java
package com.example.Config;
import org.springframework.context.annotation.Configuration;
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan({"com.example.Controller"})
@EnableWebMvc
public class SpringMvcConfig {
}
3、定义表现层控制器UserController并且定义为bean
java
package com.example.Controller;
import com.example.model.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.xml.crypto.Data;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save() {
System.out.println("User Controller save...");
return "{'info':spring-MVC}";
}
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name, int age) {
System.out.println("普通参数传递:" + name + "," + age);
return "{'Param':name & age}";
}
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName, @RequestParam("age") int MyAge) {
System.out.println("普通参数传递:" + userName + "," + MyAge);
return "{'DifferentNameParam':name & age}";
}
@RequestMapping("/PojoParam")
@ResponseBody
public String PojoParam(User user) {
System.out.println("Pojo参数传递:" + user);
return "{'User-PojoParam':name & age}";
}
@RequestMapping("/ContainPojoParam")
@ResponseBody
public String ContainPojoParam(User user) {
System.out.println("嵌套的Pojo参数传递:" + user);
return "{'User & address-PojoParam':user & age & province & city}";
}
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] arrayName) {
System.out.println("数组参数传递:" + Arrays.toString(arrayName));
return "{'Array-Param':array}";
}
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> listName) {
System.out.println("集合参数传递:" + listName);
return "{'List-Param':List}";
}
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes) {
System.out.println("列表类型使用josn参数传递:" + likes);
return "{list common for json param}";
}
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user) {
System.out.println("列表类型使用josn参数传递:" + user);
return "{pojo for json param}";
}
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> user) {
System.out.println("列表类型使用josn参数传递:" + user);
return "{list pojo for json param}";
}
@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);
System.out.println("日期类型的参数形式一传递:" + date1);
System.out.println("日期类型的参数形式二传递:" + date2);
return "{Data Param}";
}
@RequestMapping("/toJumpPage")
public String toJumpPage() {
System.out.println("跳转页面");
return "page.jsp";
}
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("jiawwwww");
user.setAge(25);
return user;
}
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("jia00000");
user1.setAge(28);
User user2 = new User();
user2.setName("jia555555");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
4、配置web容器配置类(方式一 || 方式二)
java
package com.example.Config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
原始格式,继承自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;
}
}
java
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// 简化格式,继承自AbstractAnnotationConfigDispatcherServletInitializer
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected Class<?>[] getRootConfigClasses() {
return null;
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
}
5、使用postman发送请求
6、小结
在上面的案例中,我们只需要多次完成UserController的文件编写,其他都是只需要一次编写的一劳永逸的
请求参数(get & post)
UserController.commonParam(String name,int age){} ==> 要求参数名必须要一致
UserController.commonParamDifferentName(@RequestParam("name") String userName, @RequestParam("age") int MyAge)
UserController.PojoParam(User user)
UserController.ContainPojoParam(User user) ==>嵌套的使用model
UserController.arrayParam(String[] arrayName)
UserController.listParam(@RequestParam List<String> listName)
开启josn(需要添加依赖)数据的支持:在SpringMVCConfig里面添加@EnableWebMVC,在上面的方法中加入@RequestBody
-
json普通数组(["","","",...])
-
json对象({key:value,key:value,...})
-
json对象数组([{key:value,...},{key:value,...}])
UserController.listParamForJson(@RequestBody List<String> likes)
UserController.pojoParamForJson(@RequestBody User user)
UserController.listPojoParamForJson(@RequestBody List<User> user)
注意在使用时需要调整postman传递参数的形式(1、选择body 2、text改成josn)
日期类型的导入 @DateTimeFormat
UserController.dataParam(Date date, @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2)
如何响应josn页面:返回字符型的 return "page.jsp"; 前提是page.jsp必须存在
UserController.toJumpPage()
如何响应文本文档:返回字符型的文本即可 前面的案例均会返回文本文档
如何响应josn数据:返回具体类型的对象,return user
UserController.toJsonPOJO()
如何响应josn数据集合:返回列表类型的对象
UserController.toJsonList()
代码的执行流程分析
1、代码阶段
-
服务器启动,执行 ServletContainersInitConfig 类,初始化 web 容器
-
执行 createServletApplicationContext 方法,创建了 WebApplicationContext 对象
-
加载 SpringMvcConfig 配置类
-
执行@ComponentScan 加载对应的 bean
-
加载 UserController,每个@RequestMapping 的名称对应一个具体的方法
-
执行 getServletMappings 方法,定义所有的请求都通过 SpringMVC
2、测试阶段
-
发送请求 localhost/save
-
web 容器发现所有请求都经过 SpringMVC,将请求交给 SpringMVC 处理
-
解析请求路径/save
-
由/save 匹配执行对应的方法 save()
-
执行 save()
-
检测到有@ResponseBody 直接将 save()方法的返回值作为响应求体返回给请求方
Spring的bean与SpringMVC的bean区别
Spring的bean:各种各样的组件,比如服务、数据库访问对象等,它们负责应用程序中的不同功能
SpringMVC的bean:这些 bean 更多地是与 Web 请求处理相关的,比如控制器(负责处理用户请求)、视图解析器(负责把数据展示给用户)、拦截器(用来处理请求之前或之后的逻辑)等等
如何将他们分开定义,放在不同的容器里面(SpringConfig和SpringMVCConfig)
-
方式一:Spring 加载的 bean 设定扫描范围为 com.itheima,排除掉 controller 包内的 bean
-
excludeFilters:排除扫描路径中加载的 bean,需要指定类别(type)与具体项(classes)
-
includeFilters:加载指定的 bean,需要指定类别(type)与具体项(classes)
例如在SpringConfig里面
@ComponentScan(value = "com.example",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)
)
- 方式二:Spring 加载的 bean 设定扫描范围为精准范围,例如 service 包、dao 包等
例如在SpringConfig里面
@ComponentScan({"com.example.dao","com.example.service"})
- 方式三:不区分 Spring 与 SpringMVC 的环境,加载到同一个环境中
REST风格
1、目的隐藏具体的操作行为
例如将http://localhost/user/getById?id=1 隐藏具体的操作行为变成 http://localhost/user/1
入门案例(停用UserController,使用UserController2,其他不需要改动)
2、REST的简化方式三种
解决代码中重复性较高的集中设定(RequestMappering的路径重复,method里面重复的动作)
1、在Controller类上使用@RequestMapping定义共同的访问路径。也就是在类命上方定义该类的上一级名称(在类里面的RequestMapping可以不写value)
2、使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替@RequestMapping(method=RequestMethod.XXX)
3、在Controller类上使用@RestController注解,等同于@Controller与@ResponseBody两个注解组合功能
一个案例 (books) 存在的问题 ???
1、(Book --> ServletContainerInitConfig --> SpringMvcConfig --> BookController --> SpringMvcSupport)
java
package com.itheima.domain;
public class Book {
private Integer id;
private String type;
private String name;
private String description;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", type='" + type + '\'' +
", name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
java
package com.itheima.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() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
java
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
java
package com.itheima.controller;
import com.itheima.domain.Book;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save ==> "+ book);
return "{'module':'book save success'}";
}
@GetMapping
public List<Book> getAll(){
System.out.println("book getAll is running ...");
List<Book> bookList = new ArrayList<Book>();
Book book1 = new Book();
book1.setType("计算机");
book1.setName("SpringMVC入门教程");
book1.setDescription("小试牛刀");
bookList.add(book1);
Book book2 = new Book();
book2.setType("计算机");
book2.setName("SpringMVC实战教程");
book2.setDescription("一代宗师");
bookList.add(book2);
Book book3 = new Book();
book3.setType("计算机丛书");
book3.setName("SpringMVC实战教程进阶");
book3.setDescription("一代宗师呕心创作");
bookList.add(book3);
return bookList;
}
}
java
package com.itheima.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
//设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}