目录
1、SpringMVC简介
什么是MVC
---------MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分。
1)M:Model模型层,指的是工程中的javabean,作用是存储业务数据,处理业务逻辑
2)V:View,视图层,值工程中的html或jsp等页面
3)C:controller,控制层,指工程中的Servlet,作用是接收请求和响应浏览器
---------MVC工作流程
用户通过视图层发请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller层中,Controller在根据请求处理的结果找到相应的view视图,渲染数据返回给浏览器
什么是SpringMVC
----------SpringMVC是Spring的一个后续产品,是Spring的一个子项目
----------springMVC是Spring为表述层开发提供的一整套完备的解决方案
注:三层架构分别为表述层、业务逻辑层、数据访问层,表述层表示前台页面和后台的servlet
SpringMVC特点
---------Spring家族原生产品,与IOC容器等基础无缝连接
---------- 代码清晰简洁,提升开发效率
---------基于原生的servlet,通过功能强大的前端控制器DispatcherServlet
---------性能卓越,适合现代大型的互联网项目
2、 实现HelloWorld
设置相关的pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.guigu</groupId>
<artifactId>Springmvc-dom01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <!--设置打包方式-->
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
</project>
创建web项目配置web.xml
1)扩展配置方式
创建请求控制器
由于前端控制器对浏览器发送的请求进行统一的处理,但是具体的请求有不同的处理过程,因此需要创建处理具体请求的类,即控制器
//表示控制层的bean管理和servlet一样
@Controller
public class HelloController {
}
创建视图解析器
我们都知道存放在/WEB-INF/下面的内容是不能直接通过request请求的方式请求到的,为了安全性考虑,我们通常会把jsp文件放在WEB-INF目录下,而InternalResourceView在服务器端跳转的方式可以很好的解决这个问题。
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.guigu.Controller"></context:component-scan>
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
</beans>
访问首页
public class HelloController {
//请求映射的注解
//作用当前的请求和控制器创建映射
//当浏览的路径是value的值时,那么就会映射到这个方法
@RequestMapping(value = "/")
public String index(){
//返回视图名称
return "index";
}
}
总结
浏览器发送请求,若请求地址符号前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet处理。前端控制器会读取SpringMVC的核心配置文件,通过扫描找到控制器,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析,加上前缀和后缀组成的路径,通过Thymelea对视图进行渲染,最终转发到视图所对应的页面
3、SpringMVC配置
新建一个meav工程,且配置它的web模块
配置Spring配置文件
<groupId>com.guigu</groupId>
<artifactId>springmvc-dom02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
配置web.xml文件
<!-- 注册前端控制器DispathcherServlet,对浏览器发送的请求进行统一处理-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--在web.xml中通过contextConfigLocation配置spring,contextConfigLocation参数定义了要装入的 Spring 配置文件。
如果不写任何参数配置,默认的是在/WEB-INF/applicationContext.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!--作为框架的核心组件,在启动时有大量的初始化操作要做
而这些操作放在第一次请求才会执行会严重影响访问熟读
因此需要通过这标签启动控制Dispatcherservlet的初始化时间提长-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--设置springmvc的核心控制器所能处理请求的请求路径
/代表所匹配的请求可以是/login、/html.js、/css方式
但不可是.jsp路径的请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
配置你的SpringMVC.xml
注意这个SpringMVC.xml的路径是classpath:springMVC.xml的路径
创建控制器类
@Controller
public class controller {
@RequestMapping("/")
public String index(){
return "index";
}
}
配置视图解析器
!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
4、 @RequstMapping注解
@RequstMapping注解
作用:将请求和处理请求的控制方法关联起来,建立映射关系
SpringMVC接收到指定的请求,就会找到映射关系中对应的控制器方法来处理这个请求
注解的位置
-----------位置:可以类和方法上
1)类:设置映射请求的请求路径的初始信息
2) 方法:设置映射请求路径的具体信息
//如果类和方法上都有这个RequestMapping,那么地址应该的/test/request
@RequestMapping("/request")
public String Requstmap(){
return "request";
}
@request的value属性
value是一个字符串类型的数组,表示请求映射能够匹配多个请求地址所在的请求。
@Controller("requestMapping_control")
@RequestMapping("/hello")
public class RequestMapping_control {
@RequestMapping(value = {"request","test"})
public String request(){
return "request";
}
}
@request的method属性
通过请求方式(get或post)匹配映射。它也是一个字符串数组表示
如果不设置:表示get和post请求都可以设置
@Controller("requestMapping_control")
@RequestMapping("/hello")
public class RequestMapping_control {
@RequestMapping(value = {"request","test"},
method = {RequestMethod.GET,RequestMethod.POST})
public String request(){
return "request";
}
}
@springmvc支持ant风格路径
ant风格:类型与模糊匹配
1)?:表示任意的单个字符
2)*:表示0个或者多个字符
3)**:表示任意的一层或者多层
注意在使用 * * 的时候,只能使用/ * * /xxx的方法是
@Controller("requestMapping_control")
//@RequestMapping("/hello")
public class RequestMapping_control {
@RequestMapping("/**/a")
public String request(){
return "request";
}
}
@springmvc支持路径占位符(重点)
5、SpringMVC获取请求参数
通过servletAPI获取(一般不使用)
public class param_API {
@RequestMapping("/paramApI")
public String a(HttpServletRequest request){
String name=request.getParameter("username");
String password=request.getParameter("password");
System.out.println(name+password);
return "request_param";
}
}
通过springMVC控制器形参获取请求参数
只要保证控制器的形参和请求参数名保持一致
<a th:href="@{/springmvc_ApI(username='覃圣航',password=123456)}">springmvc方式</a>
@RequestMapping("/springmvc_ApI")
public String a(String username ,String password){
System.out.println(username+password);
return "request_param";
}
多个同名参数的情况
@RequestMapping("/springmvc_ApI")
//多请求参数出现多个同名的参数[比如:在多选选项卡中的naem属性都是一样的],可以使用字符串或者字符数组的形式
//如果是字符串类型,最后结果请求参数的每一个值使用逗号进行拼接
public String a(String username ,String password,String boby){
System.out.println(username+password+boby);
return "request_param";
}
@RequestParam注解处理参数和控制器形参的映射关系
属性值
value:指定为形参赋值的请求参数的参数名
required:设置是否必须传输请求参数,默认true
defaultvalue:不管required为属性值为true还是false,当value所指定的请求参数没有或传输为空字符串传输时,使用默认值赋值
<a th:href="@{/springmvc_ApI(username='覃圣航',password=123456)}">springmvc方式</a>
@RequestMapping("/springmvc_ApI")
public String a( @RequestParam String user_name ,String password){
System.out.println(username+password);
return "request_param";
}
@RequestHerder请求头信息和控制器形参创建映射
public String a(
@RequestHeader("Host") String host){
System.out.println("host"+host);
return "request_param";
}
@CookieVlue将cookie数据和控制器形参创建映射
与@ReuqestParam和@RequestHeader用法相同
@通过POJO获取请求参数
可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值
package com.guigu.mvc.com.guigu.bean;
public class from {
private String username;
private Integer password;
private String boby;
public from() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
public String getBoby() {
return boby;
}
public void setBoby(String boby) {
this.boby = boby;
}
@Override
public String toString() {
return "from{" +
"username='" + username + '\'' +
", password=" + password +
", boby='" + boby + '\'' +
'}';
}
}
//from这个类中的属性和表单类中的属性一致,所以它会自动注入
public String a(from a) {
System.out.println(a);
return "request_param";
}
解决乱码问题
<filter>
<filter-name>CharacterEncodingFilter</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>
<!-- 设置响应的编码
是意思是指无论客户端请求是否包含了编码,都用过滤器里的编码来解析请求-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- /*和/都是将所有请求交给其配置的Servlet处理,只是/*具有最高优先级,而/优先级最低。即/*匹配所有请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
6、域对象共享数据
通过servletApI就获取Rquest对象
public class SocpControl {
@RequestMapping("/testServletAPI")
public String testServletApi(HttpServletRequest request){
request.setAttribute("ServletAPI","hello,servlet");
return "testServletAPI";
}
}
使用ModelAndView向request域对象共享数据(推荐)
MdelAndView有Model和view功能
Model:主要用于向请求域对象共享数据
View:主要用于设置视图,实现页面跳转
@RequestMapping("/modelAndview")
//用modelandview设置域对象那么返回值必须是modelandview
public ModelAndView modelAndview(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("ServletAPI","hello,modelandview");
//view设置视图,实现页面跳转
modelAndView.setViewName("testServletAPI");
return modelAndView;
}
使用Model向request域对象共享数据
@RequestMapping("/model")
public String Model(Model model){
model.addAttribute("ServletAPI","hello,model");
return "testServletAPI";
}
使用map向request域对象共享数据
public String Map(Map<String,Object> map){
map.put("ServletAPI","hello,map");
return "testServletAPI";
}
使用ModeMap向request域对象共享数据
@RequestMapping(“/modelmap”)
public String ModeMap(ModelMap modelMap){
modelMap.addAttribute(“ServletAPI”,“hello,modelmap”);
return “testServletAPI”;
}
Model、ModelMap、Map之间的关系
向serssion 域共享数据(建议)
@RequestMapping("/Session")
public String Serssion(HttpSession session){
session.setAttribute("ServletAPI","hello session");
return "testServletAPI";
}
向Application 域共享数据
7、SpringMVC视图
--------springMVC中的视图是view接口,视图的作用渲染数据,将模型Model中的数据展现给用户。
---------springmvc视图种类很多,默认有转发视图和重定向视图
---------当工程引入jstl的依赖,转发视图会自动转换为jstlview
--------若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymealeaf的视图解析器,由此视图解析器解析之后所得到的时Thymeleafview
ThymeleafView
当控制器方法中设置的视图没有任何前缀时,此时的视图名称会被SpringMVC配置文件中配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式跳转
@RequestMapping("/testView")
public String View() {
return "test_View";
}
转发视图
----------SpringMVC中默认的转发视图时internalRresourceView。
----------SpringMVC中创建转发视图的情况:当控制器方法中所设置的视图名称以“forward:”为前缀时,创建internalresouceview视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀“forward:”去掉,剩余部分作为最终路径通过转发的方式实现跳转
@RequestMapping("/thview")
public String thvew(){
return "Source";
}
@RequestMapping("/internalresouceview")
public String interview(){
return "forward:/thview";
}
重定向视图
----------SpringMVC中默认的重定向视图时RedirecView
----------当控制器方法中所设置的视图名称以“redirect”为前缀时,创建RedireView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器节气,而是将会将浅醉去掉,剩余部分作为最终路径通过重定向的方式实现跳转
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/thview";
}
视图控制器
--------当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示
--------在当前的控制器方法中没有其他的请求处理是,只需要设置一个视图名称我们用视图控制器
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
xmlns:mvc="http://www.springframework.org/schema/mvc"
<!--
path:设置处理的请求地址
view-name:设置请求地址对应的视图名称
-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
注:当springMVC中设置任何一个view-controller时,其他控制器中的请求映射全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动标签
<!--注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
Spirngmvc视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/qsh/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
8、RESTFUL(一种软件架构的风格)
RESTFUL简介
RESTful是一种软件设计规范,是客户端和服务端进行数据交互的一个规范。 早期使用JSP页面开发网页时,数据交互基本都是通过表单提交,然后通过内置对象传递。当HTML5兴起,移动互联网兴起,网站后端服务,不仅要考虑PC端的网页,也要考虑移动端数据的展示、小程序、HTML5页面等。如果需要多个终端(Android、iOS、小程序、Pad、HTML5页面)共用一个后端,一般来说主流方案就是使用JSON进行传递。RESTful则规范了请求的URL,注意RESTful只是一个规范,不是一个技术。
RESTFUL实现
post和get的实现
@RequestMapping("/qsh")
@Controller
public class UserControl {
//更具reustful风格来进行操作
// /user get 来查询所有的用户
// /user/id get 用id来查询单个用户
// /user post 添加用户信息
// /user/id Deelete 删除用户信息
// /user put 修改用户信息
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String user(){
System.out.println("查询所有信息");
return "source";
}
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String user_id(){
System.out.println("查询单个信息");
return "source";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String user_insert(String username,String password){
System.out.println("姓名"+username+"密码"+password);
System.out.println("插入信息");
return "source";
}
<body>
<a th:href="@{/qsh/user}">查询单个信息</a><br>
<a th:href="@{/qsh/user/1}">查询所有信息</a><br>
<form th:action="@{/qsh/user}" method="post">
姓名:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="submit" value="post提交">
</form>
</body>
</html>
DELETE和PUT的实现
<!--配置HiddenHttpMethodFileter来实现POST和DELETE的请求-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
想让自己的method为PUT或者DELETE,满足一下条件
必须method必须时post
必须传入参数_method
-->
<form th:action="@{/qsh/user}" method="post">
<input type="hidden" name="_method" value="put">
姓名:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="submit" value="put提交">
</form>
<form th:action="@{/qsh/user}" method="post">
<input type="hidden" name="_method" value="DELETE">
</form>
RESTFul案例
和传统的CRUD一样,实现对员工信息的增删改查
准备工作
package com.guigu.bean;
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
public Employee() {
}
public Employee(Integer id, String lastName, String email, Integer gender) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Enployee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
'}';
}
}
package com.guigu.Dao;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.guigu.bean.Employee;
public class Employeedao {
private static Map<Integer, Employee> employees = null;
static{
employees = new HashMap<Integer, Employee>();
employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));
employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));
employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));
employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));
employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));
}
private static Integer initId = 1006;
public void save(Employee employee){
if(employee.getId() == null){
employee.setId(initId++);
}
employees.put(employee.getId(), employee);
}
public Collection<Employee> getAll(){
return employees.values();
}
public Employee get(Integer id){
return employees.get(id);
}
public void delete(Integer id){
employees.remove(id);
}
}
功能列表
查看首页
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:annotation-driven></mvc:annotation-driven>
列表功能
@RequestMapping(value = "/Employee_list",method = RequestMethod.GET)
public ModelAndView Employee_list(){
Collection<Employee> all = employeedao.getAll();
System.out.println(all.toString());
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("employeedao_list",all);
modelAndView.setViewName("Empolyee_list");
return modelAndView;
}
<table border="1" cellpadding="0" th:cellpadding="0" style="text-align: center">
<th colspan="5">查询出所有的信息</th>
<tr>
<td>id</td>
<td>lastname</td>
<td>email</td>
<td>gender</td>
<td>options</td>
</tr>
<tr th:each="employee : ${employeedao_list}" >
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<a href="">delete</a>
<a href="">update</a>
</td>
</tr>
删除功能
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" cellpadding="0" th:cellpadding="0" style="text-align: center">
<th colspan="5">查询出所有的信息</th>
<tr>
<td>id</td>
<td>lastname</td>
<td>email</td>
<td>gender</td>
<td>options</td>
</tr>
<tr th:each="employee : ${employeedao_list}" >
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<a th:href="@{'/Employee/'+${employee.id}}">delete</a>
<a href="">update</a>
</td>
</tr>
</table>
<!--
我们通过超链接绑定表单,来实现put请求
我们用vue来经行表单和删除超链接的绑定
vue:自己了解
-->
<form method="post">
<input type="hidden" name="_method" value="delete">
</form>
</body>
</html>
插入
<form method="post" th:action="@{/Employee_list}">
lastname<input type="text" name="lastName"><br>
email:<input type="text" name="email"><br>
gender:<input type="radio" name="gender" value="1" >
<input type="radio" name="gender" value="0" ><br>
<input type="submit" value="表单提交">
</form>
</body>
</html>
@RequestMapping(value = "/Employee_list",method = RequestMethod.POST)
public String insert (Employee employee){
employeedao.save(employee);
return "redirect:Employee_list";
}
查询单个表
<td>
<a th:href="@{'/Employee/'+${employee.id}}">delete</a>
<a th:href="@{'/Employee_list/'+${employee.id}}">update</a>
<a th:href="@{/toAdd}">insert</a>
</td>
@RequestMapping(value = "/Employee_list/{id}",method = RequestMethod.GET)
public ModelAndView uodate (@PathVariable("id") Integer id){
ModelAndView modelAndView = new ModelAndView();
Employee employee = employeedao.get(id);
modelAndView.addObject("employee",employee);
modelAndView.setViewName("update");
return modelAndView;
}
修改单条记录
<body>
<form method="post" th:action="@{/Employee_list}">
<input type="hidden" name="_method" value="put" >
<input type="hidden" name="_method" th:value="${employee.id}">
lastname<input type="text" name="lastName" th:value="${employee.lastName}"><br>
email:<input type="text" name="email" th:value="${employee.email}"><br>
gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}" >
<input type="radio" name="gender" value="0" th:field="${employee.gender}" ><br>
<input type="submit" value="表单提交">
</form>
</body>
@RequestMapping(value = "/Employee_list",method = RequestMethod.PUT)
public String uodate (Employee employee){
System.out.println("我被执行了");
employeedao.save(employee);
return "redirect:Employee_list";
}
处理静态资源
<!--开放对静态资源的访问
当DispatcherServlet无法解析的时候
我们通过apache-tomcat-的defaultservlet来解析
-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--
default-servlet-handler和annotation-driven要一起用,若不配置所有请求将会被DispatcherServlet解析
-->
<mvc:annotation-driven></mvc:annotation-driven>
9、HttpMessageConverter
HttoMessageConverter,报文信息转换器,将请求报文转换为java对象,或者将java对象转换为响应报文HttpMessageConverter提供了两个注解和两个类型:@RequestBoby、@ResponseBody、RequestEntity、ResponseEntity
@RequestBody
@RequstBody可以获取请求体,需要在控制器方法中设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值
<form th:action="@{/request}" method="post">
name: <input type="text" name="name"><br>
password:<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
</html>
@Controller
public class Httprequest {
@RequestMapping("/request")
public String index(@RequestBody String requestbody){
System.out.println("requestbody"+requestbody);
return "index";
}
}
RequestEntity
RequestEntity封装请求报文的一种类型,需要在控制器方法中设置该类型的形参,当前请求的请求报文就会赋值给该形参,可以通过getHeader()获取请求头信息,通过getBody()获取请求体信息
@RequestMapping("/request_entity")
public String index(@RequestBody RequestEntity<String> requestbody){
System.out.println("请求体信息"+requestbody.getBody());
System.out.println("请求头信息"+requestbody.getHeaders());
return "index";
}
@ResponseBody
@ResponseBod用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体传给浏览器
@RequestMapping("/respose")
@ResponseBody
//加上 @ResponseBody这个注解的方法那他的返回值就代表响应体
public String respose(){
System.out.println("我被执行了");
return "这是响应的数据";
}
处理json数据
@RestConroller注解
@RestController注解是Springmvc提供的一个复合注解,标识在控制器的类上,相当于为类添加了@Conroll注解,并且为其中没一个方法添加了@ResponseBody注解
ResponseEntity
ResponseEntity用于控制方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文。(主要可以用来:文件下载)
10、文件下载和上传
下载
@RequestMapping("/filedown")
public ResponseEntity<byte[]> down(HttpSession session) throws IOException {
//获取servletcontext对象
//ServletContext对象代表整个web应用,可以和程序的容器(服务器)来通信。
ServletContext servletContext= session.getServletContext();
//获取服务器中文件的真实路径
//ServletContext.getRealPath() 是从当前servlet 在tomcat 中的存放文件夹开始计算起的
String realPath = servletContext.getRealPath("/static/1.jpg");
//创建输入流
FileInputStream fileInputStream = new FileInputStream(realPath);
//创建byte数组
//fileInputStream.available()返回fileInputStream的字长
byte[] bytes=new byte[fileInputStream.available()];
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
fileInputStream.close();
return responseEntity;
文件的上传
<body>
<!--文件上传必须是post方法
application/x-www-form-urlencoded:表示文件以二进制的方式不以{name:vale}的方式发给服务器
-->
<form th:action="@{/fileup}" method="post" enctype="application/x-www-form-urlencoded">
头像<input type="file" name="photo">
<input type="submit">
</form>
</body>
1、添加依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2、SpringMVC的配置文件中添加配置:
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题,使用uuid保证文件名不重复
String hzName = fileName.substring(fileName.lastIndexOf("."));
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if(!file.exists()){
file.mkdir();
}
//其实 File.separator 的作用相当于 ' \ '
String finalPath = photoPath + File.separator + fileName;
//实现上传功能
//transferTo:文件上传
photo.transferTo(new File(finalPath));
return "success";
}
11、拦截器
用于视图控制器(Dispacher)进行预处理和后处理,开发者可以自己定义一些拦截器来实现特定的功能
创建拦截器
继承Handlinterceptor
public class testintercepterl implements HandlerInterceptor {
@Override
//在控制器方法调用前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
//在控制器方法调用前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//视图渲染之前
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
配置拦截器
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:interceptors>
<!--表示你的那给类来作为拦截器,表示对所有请求进行了拦截-->
<bean class="com.guigu.interceper.testintercepterl"></bean>
<!--可以自己来设置拦截器规则-->
<mvc:interceptor>
<mvc:mapping path="/**"/><!--要拦截的路径,在拦截器中用/**/表示所有请求而部署/*-->
<mvc:exclude-mapping path="/"/><!--表示你可以路径进行排除,不用被拦截器进行拦截-->
<bean class="com.guigu.interceper.testintercepterl"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器的三个抽象方法
perHandle,控制器方法在执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法。
postHandle:控制器方法执行之后执行postHandle
afterComlation:处理完视图和模型数据,渲染视图完毕之后afterComplation()
多个拦截器的执行顺序
12、异常处理器
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionReslover;
HandleExceptionReslover有两个实现类:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver;
SpringMVC提供了自定义的异常处理器SimpleMappingMVCExceptionResolver使用方式;
<!--配置异常解析器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--exceptionMappings是properos类型是键值对方式赋值-->
<property name="exceptionMappings">
<props>
<!--key表示的是你出现异常的类型-->
<prop key="java.lang.ArithmeticException">
<!--表示你出现异常要跳转的页面-->
Error
</prop>
</props>
</property>
<!--exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域进行共享-->
<property name="exceptionAttribute" value="ex"></property>
</bean>
基于注解的异常处理
ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。最常用的就是异常处理
@ControllerAdvice
public class ExceptionController {
//当程序出现vlue中的错误的时候,会执行ExceptionHandler标注的方法
@ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
public String testexecption(Exception ex , Model model){
model.addAttribute("ex",ex);
return "Error";
}
}
13、注解配置springmvc
使用配置类和注解代替web.xml和springmvcc配置文件的功能
@Configuration注解的作用:声明一个类为配置类,用于取代bean.xml配置文件注册bean对象。
创建初始化类,代替web.xml
//web工程的初始了类,用来代替web.xml
public class WEB extends AbstractAnnotationConfigDispatcherServletInitializer {
//用来写spring配置文件
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{Springconfig.class};
}
//用来写springmvc配置文件
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Springmvcconfig.class};
}
//指定DispatcheerServletD的映射路径,即url-patten
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//指定监听器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter=new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
HiddenHttpMethodFilter hiddenHttpMethodFilter=new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};
}
}
创建SpringConfig配置类,代替spring配置文件
@Configuration
public class SpringConfig {
//ssm整合之后,spring的配置信息写在此类中
}
创建Springmvc配置类,代替springMV的配置文件
//用来代替springmvc的配置文件
//1、扫描主键 2、视图解析器 3、view-controller 4、default-servlet-handler
//5、mvc注解驱动 6、文件上传解析器 7、异常处理器 8、拦截器
@Configuration //表示配置类
@ComponentScan("com.guigu.springmvc.controll") //扫描主键
@EnableWebMvc //开启MVC注解驱动
public class Springmvcconfig implements WebMvcConfigurer {
//WebMvcConfigurer接口提供了很多方法,用来配置以上组键的方法
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
testinterceptor testinterceptor = new testinterceptor();
registry.addInterceptor(testinterceptor).addPathPatterns("/**");
}
//配置view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//配置default-servlet-handler
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//@bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理,
//产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
//应为在xml文件中文件上传解析器就是配置了一个bean所以我们就配置bean标签即可
@Bean
public MultipartResolver multipartResolver( ){
CommonsMultipartResolver commonsMultipartResolver1 = new CommonsMultipartResolver();
return commonsMultipartResolver1;
}
//配置生成模板解析器
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
// ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(
webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/qsh/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//生成模板引擎并为模板引擎注入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//生成视图解析器并未解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
SpringMVC执行流程
常用组件
DispatcherServlet:前端控制器,不需要工程师开发,由框架提供。作用:统一处理请求和响应,整个流程控制的中心,由它调用其他组件处理用户请求。
HandlerMapping:处理映射器,不需要工程师开发,由框架提供。作用:根据请求的url、method等信息找到Handler,即控制器方法
Handler:处理器,需要工程师开发。作用:在DispatcherServlet的控制下Handler具体的用户请求进行处理
HandlerAdapter:处理适配器,不需要工程师开发,由框架提供。作用:通过HandlerApapter对处理器(控制器方法)进行执行
ViewResoler:视图解析器,不需要工程师开发,由框架提供。作用:进行视图解析,得到相应的视图,例如:ThymeleafVew、internalResourceView,RedirctView
VIew:视图,作用:将模型数据通过页面展示给用户
执行流程
-----------1、用户向服务器发送请求,请求被SpringMVC前端控制器DisPatcherServlet捕获
-----------2、DisPatcherServlet对请求URL解析,判断url进行映射
a)不存在
判断是否配置了mvc:default-servlet-handler‘
没有配置,控制台无法找到映射
如果配置了,则访问目标资源(一般是静态资源,jss,html),找不到客户端404
----------3、若存在
更具url,调用HanderMapping获得该Handler配置的相关对象(控制器方法,拦截器)