学习视频时B站的狂神说的视频
https://www.bilibili.com/video/BV1aE41167Tu
1.SpringMVC
MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
- 模型(dao、service):用于存储数据以及处理用户请求的业务逻辑。
- 视图(jsp):向控制器提交数据,显示模型中的数据。
- 控制器(servlet):根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。
导入jar包
<!--导入依赖-->
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
MVC需要做的事情
- 将url映射到java类或者是java方法
- 封装用户提交的数据
- 处理请求–调用相关的业务处理–封装响应数据
- 将相应的数据进行渲染.jsp/html等表示层数据
Spring MVC 的执行流程
2.HelloMvc
-
在web.xml配置DispatcherServlet
<!--注册DispatcherServlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 关联一个springmvc的配置文件:【servlet-name】-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet.xml</param-value> </init-param> <!--设置启动级别--> <load-on-startup>1</load-on-startup> </servlet> <!-- /:配置所有请求(不包括.jsp) /*:配置所有请求(包括.jsp) --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
配置spring-servlet.xml
<!--添加处理器映射器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!--添加处理器适配器--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!--添加视图解析器:DispatcherServlet给他的ModelAndView--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> <!--Handler--> <bean id="/hello" class="com.kuang.controller.HelloController"/>
-
配置Controller(最初始版本,不常用)
public class HelloController implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { //ModelAndView 模型视图 ModelAndView mv = new ModelAndView(); //封装对象放到ModelAndView中 mv.addObject("msg","helloSpringMVC"); //疯转要跳转的视图,放在ModelAndView中 mv.setViewName("hello");// /WEB-INF/jsp/hello.jsp return mv; } }
-
创建前端jsp页面,测试
这里会遇到404问题
因为IDEA中虽然导入了包,但是项目中没有lib依赖
打开项目结构到Artifacts为项目的WEB-INF文件夹中创建一个lib文件夹并将所有的library导入其中,重启Tomcat
3.注解配置Controller
- 再web.xml中配置DispatcherServlet并且加载Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载Spring配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 设置启动级别 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 配置Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 走动扫描包 -->
<context:component-scan base-package="com.kuang.controller"/>
<!-- 让mvc不处理静态资源 .css .html .js .mp3 .mp4 ... -->
<mvc:default-servlet-handler/>
<!-- 自动配置 处理器适配器 和处理器映射器 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- 通过注解配置Controller层
@Controller//创建Controller
//加载URL的一级路径
@RequestMapping("/h1")
public class HelloController {
//加载URL的二级路径
@RequestMapping("/hello")
public String hello(Model model){
//向Model中添加数据
model.addAttribute("msg","Hello Spring MVC");
//视图层的地址,会被试图解析器拼接
return "hello";
}
}
- 创建试图层,测试
4.创建Controller的方法
1.实现Controller接口【不推荐使用】
-
通过实现接口创建Controller
public class Controllertest1 implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg","接口实现Controller"); mv.setViewName("test1"); return mv; } }
-
Spring配置中需要配置url路径(其中的处理器映射器和处理器适配器可以省略,但是视图解析器不可以省略)
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="/test1" class="com.kuang.controller.Controllertest1"/>
2.通过注解【推荐使用】
//四个等效注解
@Component //组件
@Controller //控制层
@Service //service层
@Repository //dao层
-
首先要通过Spring配置文件,使程序可以扫描和支持注解
<context:component-scan base-package="com.kuang.controller"/> <mvc:default-servlet-handler/> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
-
通过注解配置Controller
@Controller public class Controllertest2 { @RequestMapping("/test2") public String test2(Model model){ model.addAttribute("msg","通过注解创建Controller"); return "test1"; } }
-
测试
5.RestFul风格
传统方式操作资源:通过不同的参数来实现不同的效果!方法单一,post和get
- http://127.0.0.1/item/queryItem.action?id=1 查询,GET
- http://127.0.0.1/item/saveItem.action新增,POST
- http://127.0.0.1/item/updateItem.action 更新,POST
- http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
RestFul操作资源:可以用过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同
- http://127.0.0.1/item/1 查询,GET
- http://127.0.0.1/item新增,POST
- http://127.0.0.1/item 更新,PUT
- http://127.0.0.1/item/1 删除,DELETE
RestFul可以使用/来传参
@Controller
public class RestFulController {
// 最初始的请求方式 http://localhost:8080/add?a=1&b=2
@RequestMapping("/add")
public String test1(int a, int b, Model model){
int res = a+b;
model.addAttribute("msg","结果为"+res);
return "test1";
}
// 使用RestFul风格 http://localhost:8080/add2/1/8
@RequestMapping("/add2/{a}/{b}")
public String test2(@PathVariable int a, @PathVariable int b, Model model){
int res = a+b;
model.addAttribute("msg","结果为"+res);
return "test1";
}
}
RestFul捕获不同的请求
-
可以设置RequestMapping的method属性
@RequestMapping(value = "/add2/{a}/{b}",method = RequestMethod.GET) public String test2(@PathVariable int a, @PathVariable int b, Model model) { int res = a + b; model.addAttribute("msg", "Get结果为" + res); return "test1"; } @RequestMapping(value = "/add2/{a}/{b}",method = RequestMethod.POST) public String test3(@PathVariable int a, @PathVariable int b, Model model) { int res = a + b; model.addAttribute("msg", "Post结果为" + res); return "test1"; }
-
可以使用指定注解获取
// @RequestMapping(value = "/add2/{a}/{b}",method = RequestMethod.GET) @GetMapping("/add2/{a}/{b}") public String test2(@PathVariable int a, @PathVariable int b, Model model) { int res = a + b; model.addAttribute("msg", "Get结果为" + res); return "test1"; } // @RequestMapping(value = "/add2/{a}/{b}",method = RequestMethod.POST) @PostMapping("/add2/{a}/{b}") public String test3(@PathVariable int a, @PathVariable int b, Model model) { int res = a + b; model.addAttribute("msg", "Post结果为" + res); return "test1"; }
6.结果跳转方式
1.ModelAndView
根据View的名称和试图解析器跳到指定的页面
页面:(解析器前缀)+viewName+(解析器后缀)
2.Servlet API
- 通过HttpServletResponse进行输出
- 通过HttpServletResponse实现重定向
- 通过HttpServletResponse实现转发
reponse的sendRedirect(“目标地址”);
request的getRequestDispatcher(“目标地址”).forword(request,response);
3.SpringMVC
-
根据return的字符串和视图解析器跳到指定的页面
页面:(解析器前缀)+String字符串+(解析器后缀)
-
return中可以使用forward来跳转其他资源的目的
-
return中可以使用redirect来实现重定向
7.数据处理
当前端的参数名与后端参数名相同时
//localhost:8080/u1/t1?name="dong"
@GetMapping("t1")
public String test1(Model model, String name){
//接受参数
System.out.println("参数为"+name);//参数为"dong"
//将结果返回前端
model.addAttribute("msg",name);
//页面跳转
return "test1";
}
当前端的参数与后端参数名不相同时
//http://localhost:8080/u1/t2?name1="dong"
@GetMapping("t2")
public String test2(Model model,@RequestParam("name1") String name){
//接受参数
System.out.println("参数为"+name);//参数为"dong"
//将结果返回前端
model.addAttribute("msg",name);
//页面跳转
return "test1";
}
当前端传入的是一个对象
- 首先直接匹配参数名,如果没有
- 再匹配对象中的参数名
//http://localhost:8080/u1/t3?id=1&name=“123”&age=4
@GetMapping("t3")
public String test3(Model model,User user){
//接受参数
System.out.println("参数为"+user);//参数为User(id=1, name="123", age=4)
//将结果返回前端
model.addAttribute("msg",user);
//页面跳转
return "test1";
}
8.数据显示到前端
-
使用ModelAndView
-
使用Model
-
使用ModelMap
继承了LinkedHashMap拥有HashMap的方法
9.乱码问题
过滤器解决乱码
public class EncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
}
}
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.kuang.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
通过Spring解决乱码问题
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/*
#### 通过Spring解决乱码问题
```xml
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>