SpringMVC

目录

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>

        <!-- Spring5Thymeleaf整合包 -->
        <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数据

在这里插入图片描述
什么是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配置的相关对象(控制器方法,拦截器)
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值