Spring - SpringMVC(一)

SpringMVC

第一章-SpringMVC入门

补充:浏览器地址中的绝对路径

/ ,代表的就是端口后面,哪怕你在配置文件中配置了项目的映射名,也是端口后面,不是映射名后面,它会直接忽视项目的映射名,只代表端口后边。

知识点-概述

1. 目标

  • 了解什么是SpringMVC

2. 路径

  1. 三层架构
  2. SpringMVC介绍

3. 详解

3.1 三层架构

服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构

  • 三层架构

    ​ 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型

    ​ 业务层:处理公司具体的业务逻辑的

    ​ 持久层:用来操作数据库的

  • MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。

    ​ Model:数据模型,JavaBean的类,用来进行数据封装。

    ​ View:指JSP、HTML用来展示数据给用户

    ​ Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等(Hibernate Validator)

3.2 SpringMVC
3.2.1 概述
  • SpringMVC是一种基于Java的、实现MVC设计模型的、请求驱动类型的(基于HTTP协议)、轻量级Web框架,属于 Spring FrameWork 的后续产品。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
  • SpringMVC已经成为目前最主流的 MVC 框架之一,并且随着Spring3.0的发布,全面超越 Struts2,成为最优秀的 MVC(web层的) 框架。
  • 它通过一套注解,让一个简单的Java类成为处理请求的控制器(Controller),而无须实现任何接口(跟Servlet对比)。同时它还支持RESTful编程风格的请求。
3.2.2 SpringMVC的优点

1.清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping) :负责找controller类
处理器适配器(HandlerAdapter) : 负责调用controller类,得到结果,封装结果
视图解析器(ViewResolver) : 负责解析view
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
3、由于命令对象就是一个 POJO, 无需继承框架特定 API,可以使用命令对象直接作为业务对象。

4、和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
5、可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
6、可定制性, HandlerMapping、 ViewResolver 等能够非常简单的定制。
7、功能强大的数据验证、格式化、绑定机制。
8、利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的 JSP 标签库,使 JSP 编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。

4. 小结

  1. Spring MVC 是Spring开发的关于Web层的框架
  2. 它的作用:接收请求,调用service,响应结果

案例-快速入门【重点】

1.需求

  • 浏览器请求服务器(SpringMVC), 响应成功页面

2. 分析

  1. 创建maven工程,导入依赖
  2. 创建Controller, 处理的请求
  3. 创建一个index.jsp页面, success.jsp
  4. 配置springmvc.xml
  5. 配置web.xml 启动时加载springmvc.xml 【配置DispatcherServlet】

3. 实现

3.1 导入依赖
<dependencies>
    <!--springmvc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency> 
    <!--jsp-api-->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
        <scope>provided</scope>
    </dependency>
    <!--servlet-api-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
3.2 编写页面

在webapp里创建index.jsp

<%--
  Created by IntelliJ IDEA.
  User: xiaomi
  Date: 2021/9/9
  Time: 9:06
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>这是首页~</h2>
<a href="/sayHi">点我发起请求</a>
</body>
</html>


在webapp里创建success.jsp

<%--
  Created by IntelliJ IDEA.
  User: xiaomi
  Date: 2021/9/9
  Time: 9:06
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>这是成功的页面~</h2>

</body>
</html>

3.3 编写Controller
  • com.mingye.controller包中创建类Controller01
  • 类上增加@Controller注解,声明成为一个bean
  • 创建sayHi方法,并在方法上增加@RequestMapping注解,声明方法的访问路径
/*
    @Controller:
        1. 标记了这个类专门是用来处理请求的,它就是一个控制器!
            1.1 springmvc会扫描这个注解标注的类,然后创建对象,使用IOC容器管理起来。
            1.2 这个类当中所有@RequestMapping标注的方法全部会被当成是 页面的路径地址!
     @RequestMapping:
        1. 标记这个方法它的映射路径地址,也就是什么请求过来的时候,会执行这个方法!
        2. 属性介绍:
            value: 用来设置映射地址
            method: 用来设置请求方式
                RequestMethod.POST: 处理POST请求
                RequestMethod.GET: 处理GET请求
            params: 要求一定要携带指定的参数
 */

@Controller
public class Controller01 {

    @RequestMapping(value = "/sayHi03", params ={"name=admin" , "password=123"}, method ={RequestMethod.POST , RequestMethod.GET} )
    public String sayHi03(){
        System.out.println("hi~03!~! springmvc...");
        return "success";
    }

    /*
        使用物理视图跳转:
            1. 返回值是页面的完整地址。看起来直观,但是写起来麻烦!
     */
    @RequestMapping("/sayHi")
    public String sayHi(){
        System.out.println("hi~!~! springmvc...");
        return "/success.jsp";
    }

    /*
        使用逻辑视图跳转:
            1. 返回值写起来简单,但是不直观。看不出来是哪个页面
            2. 需要搭配视图解析器才能识别是哪里的页面
     */
    @RequestMapping("/sayHi02")
    public String sayHi02(){
        System.out.println("hi~02!~! springmvc...");
        return "success";
    }
}

3.4 编写配置文件

resources中创建springmvc的配置文件springmvc.xml , 这个名字可以随意,也可以写成前几天的 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

  
    <!--1. 扫描包-->
    <context:component-scan base-package="com.mingye"/>
</beans>
3.5 修改Web.xml

webapp/WEB-INF/web.xml中配置前端控制器DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<!--登记|注册 DispatcherServlet,让它来抓请求-->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


		<!--1. 告诉DispatcherServlet,springmvc配置文件在哪里。它会解析这个文件,进而去扫描包-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>

		<!--2. 让DispatcherServlet初始的时机提前到项目发布-->
		<load-on-startup>1</load-on-startup>
	</servlet>


	<servlet-mapping>
		<servlet-name>dispacher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>
3.6 运行测试
  • 启动项目,点击首页的超链接访问Controller
  • sayHi方法被访问到,并且页面跳转到了success.jsp

4. 小结

  1. 创建web工程,导入依赖:spring-webmvc, servlet-api, jsp-api
  2. 编写Controller
  3. 提供springmvc.xml:开启组件扫描
  4. 修改web.xml:配置前端控制器DispatcherServlet

知识点-配置详解

1. 目标

  • 掌握入门案例执行流程

  • 掌握入门案例的配置

2. 路径

  1. 原理分析
  2. springmvc.xml的配置
  3. web.xml的配置
  4. controller的配置

3. 讲解

3.1. 原理分析
3.1.1 请求响应流程
代码运行流程
3.1.2 三大组件
  • HandlerMapping处理器映射器
    • 作用:根据客户端请求的资源路径,查找匹配的Controller及拦截器(类似过滤器)链
  • HandlerAdapter处理器适配器
    • 作用:用于适配调用不同的Controller 执行Controller,得到模型和视图
  • ViewResolver视图解析器
    • 作用:用于解析视图,根据视图路径找到真实视图(页面)
3.1.3 详细执行流程
  1. 客户端发请求到DispatcherServlet
  2. DispatcherServlet
    1. 通过HandlerMapping处理器映射器,根据请求路径,查找匹配的Controller及拦截器
    2. 得到要执行的Controller和拦截器(执行链)
  3. DispatcherServlet
    1. 通过HandlerAdapter处理器适配器,调用控制器Controller
    2. 得到ModelAndView对象(其中View指视图路径,Model要响应的数据对象)
  4. DispatcherServlet
    1. 通过ViewResolver解析视图,得到真实视图(视图路径对应的页面)
    2. 渲染视图(把Model里的数据填充到View里 , 替换页面上的 EL表达式为真实的数据)
  5. 把最终渲染的结果,响应到客户端
3.2. springmvc.xml的配置

跟前几天的 applicationContext.xml 是一样的。只是换了个名字而已。springmvc和spring可以共用同一个配置文件!

3.2.1 基本配置示例
<!--开启组件扫描-->
<context:component-scan base-package="com.mingye.controller"/>

<!--开启mvc的注解驱动-->
<mvc:annotation-driven/>

<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<!-- 静态资源的配置:让SpringMVC不处理静态资源 -->
<mvc:default-servlet-Handler/>
3.2.2 mvc的注解驱动
配置语法
    <!--
        2. 注解驱动
            2.1 标签一定要选择默认是mvc的标签,如果选择到cache的标签,则会出现这个错误:
                No bean named 'cacheManager' available
            2.2 这个标签会帮助我们在项目里面导入三大组件
            2.3 后面用到的一些注解,必须要有这个标签的支撑,否则注解用不了! @ResponseBody
    -->
    <mvc:annotation-driven/>
配置说明
  • 在SpringMVC中,处理器映射器,处理器适配器,视图解析器 被称为三大组件
  • 在springmvc.xml中配置<mvc:annotation-driven/>标签,可以加载SpringMVC的组件
    • 如果没有此项配置,SpringMVC也会自动加载组件,所以快速入门中,不配置这一项也可以
    • 但是后边课程中,这个标签还有其它作用,所以要配置上
3.2.3 视图解析器设置
1) 视图路径的配置方式
  • SpringMVC把页面称为视图,例如JSP|HTML页面就是视图。Controller的方法中,返回的字符串就是跳转的视图(页面)路径
  • 视图的路径有两种写法:
    • 物理视图:/success.jsp | success.jsp ,即:视图的真实路径(完整路径)
      • 直观,但是写起来麻烦
      • 例如: 如果有一个页面page.jsp 位于 /webapp/a/b/c/page.jsp , 那么物理视图返回: “/a/b/c/page.jsp”;
    • 逻辑视图:success,需要配合视图解析器,才能得到真实路径
      • 不直观,但是写起来简单
      • 例如: 如果有一个页面page.jsp 位于 /webapp/a/b/c/page.jsp , 那么逻辑视图返回: “page”
2) 物理视图的配置方式
  • Controller的方法中,直接返回物理视图路径。
  • 不需要配置视图解析器
@Controller
public class Controller01 { 

    //物理视图跳转: 要写完整的路径地址
    @RequestMapping("/sayHi02")
    public String sayHi02(){
        System.out.println("调用了Controller01的sayHi02方法~!~");
        return "/a/b/c/success.jsp";
    }
}
3) 逻辑视图的配置方式
  • springmvc.xml中增加以下内容:
  <!--
        3. 视图解析器
            3.1 视图解析器是搭配逻辑视图使用的,它要和方法的返回值拼接起来得到页面的真实路径
                前缀  +  方法的返回值  +  后缀    ====   /success.jsp
            3.2 视图解析器一旦配置,就会对全局产生影响,所有的controller的方法返回值都要受到它的影响
                除了某些方法之外【明天讲!】
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
  • Controller中修改代码,简化方法返回值
@Controller
public class Controller01 {
    //逻辑视图跳转:只要写页面的名字即可,需要搭配视图解析器来使用
    @RequestMapping("/sayHi03")
    public String sayHi03(){
        System.out.println("调用了Controller01的sayHi03方法~!~");
        return "success";
    }
}
  • 由视图解析器,帮我们把prefix + "success" + suffix,拼接成物理视图/success.jsp
3.2.4 处理静态资源
2.4.1 请求静态资源的说明
  • 使用SpringMVC时,客户端访问静态资源时,会访问不到 , 会得到404

  • Tomcat本身具备处理静态资源的能力,但是我们配置的DispatcherServlet把Tomcat的默认处理器覆盖掉了;而DispatcherServlet没有处理静态资源的能力,所以:访问不到静态资源

    Tomcat里面有一个Servlet,可以处理静态资源: DefaultServlet,它的映射路径是 /

    我们使用SpringMVC的时候,在web.xml中,配置DispatcherServlet,配置的地址路径也是 /

2.4.2 两种配置方式解决问题

方案一:指定静态资源的位置

  • 针对客户端对静态资源的请求,指定资源所在的位置。让SpringMVC直接去指定目录下加载
  • 示例:
  <!--    4. 静态资源处理:
                4.1 当我们的DispatcherServlet配置的映射路径是 / 的时候,静态资源就看不到了,报:404的错误
                    a. 在tomcat里面有一个默认的DefaultServlet, 它的映射路径是 / 它的作用是专门用来处理静态资源
                    b. 由于DispatcherServlet,映射路径也是 /  所以咱们的DispatcherServlet把DefaultServlet给
                        覆盖了。而且DispatcherServlet 又不能处理静态资源

                4.2 解决静态资源的问题,有两种办法:
                    a. 配置映射地址和资源路径。
                    b. 把静态资源的请求,交还给tomcat的DefaultServlet处理
    -->
        <!--
            1. 配置地址和路径的映射
                a. 不推荐使用这种办法,因为以后如果还有新的静态资源的类型,那么就需要在这里再增加一行配置
                b. 解释:
                    mvc:resources : 用来做请求地址和资源路径映射
                        mapping : 请求地址
                            * : 表示当前的位置,只能匹配一级目录
                                /html/*   ========不能匹配==========localhost:82/html/my.html
                                /html/* ========不能匹配==========localhost:82/html/a/b/c/my.html
                            ** : 表示匹配任意目录
                                /html/**   ========能匹配==========localhost:82/html/my.html
                                /html/** ========能匹配==========localhost:82/html/a/b/c/my.html
                        location : 静态资源所在位置 , 后面要有 / 结尾
         -->
   <mvc:resources mapping="/html/**" location="/html/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/css/**" location="/css/"/>

方案二:由Tomcat处理静态资源(推荐)

  • 如果客户端请求了静态资源,DispatcherServlet处理不了,就交给Tomcat的原生Servlet来处理
  • 示例:
    <!--2. 把静态资源的处理,交给tomcat的DefaultServlet来做-->
    <mvc:default-servlet-handler/>
小结
  • 配置视图解析器

    • Controller里的方法返回值要写逻辑视图
    • 再配置视图解析器
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/"/>
         <property name="suffix" value=".jsp"/>
    </bean>
    
  • 如果有静态资源要访问,把静态资源仍然交给Tomcat处理

    <mvc:default-servlet-handler/>
    
  • 开启mvc的注解驱动:会注册一些组件,提供一些功能

    <mvc:annotation-driven/>
    
  • 开启组件扫描

    <context:component-scan base-pcakge="com.mingye.controller"/>
    
3.3. web.xml的配置
3.3.1 配置示例
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<!--登记|注册 DispatcherServlet,让它来抓请求-->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


		<!--1. 告诉DispatcherServlet,springmvc配置文件在哪里。它会解析这个文件,进而去扫描包-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>

		<!--2. 让DispatcherServlet初始的时机提前到项目发布-->
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!--
		DispatcherServlet的映射路径应该写什么呢?
			1. 映射路径能不能写成 *.do *.itheima 这样的写法呢?【也就是说,只抓尾巴】
				a. 可以!并且它不会覆盖掉Tomcat里面的DefaultServlet,也不需要写静态资源处理配置
				b. 有一点不好的地方就是:访问所有的controller方法,都必须带上尾巴 .do

			2. 映射路径能不能写成 /*  这样的写法呢?
				不可以! jsp页面看不到了! 看到的只是jsp页面的源码
				a. 在tomcat里面还有一个Servlet叫做:JspServlet, 它专门用来处理jsp页面的请求
				b. 这个JspServlet的映射路径是 *.jsp
				c. 现在DispatcherServlet,映射的路径是 /* ,那么就会涉及到一个优先级的问题!
				d. 映射路径的优先级是这样: /aa >  /*  > *.jsp | *.do >  /

				综上所述:
					1. 当DispatcherServlet配置的映射路径是 /*的时候,浏览器访问jsp页面这个请求,也会被它抓住
					但是DispatcherServlet又不能解析,执行jsp页面,所以直接把这个页面的源码丢给了浏览器!

					2. / 表示缺省配置,优先级是最低!所谓的缺省配置就是当没有任何servlet处理这个请求的时候,就由它来处理!
	-->
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>
3.3.2 配置说明
  • load-on-startup:配置Servlet的创建时机,值是整数
    • 如果是正整数,表示服务器一启动就要创建Servlet对象。数值越小,创建的越早
    • 如果是0或者负数,表示默认的:第一次访问时,创建Servlet对象
    • DispatcherServlet是SpringMVC一切功能的基础和核心,要求:服务器启动时就创建,并且要最早创建,所以设置值为1
  • init-param:配置Servlet的初始化参数
    • contextConfigLocation:配置springmvc.xml的路径,让DispatcherServlet被创建时,加载配置文件,初始化Spring容器
  • url-pattern:配置Servlet的路径,通常配置为/
拓展:DispatcherServlet配置成//*的区别:
  • 对JSP的处理不同。当客户端请求了xxx.jsp

  • 如果DispatcherServlet配置的是/*,不能正常访问JSP

    • /*是目录匹配,优先级高于扩展名匹配(Tomcat里有JspServlet,路径是*.jsp
    • 必定是由DispatcherServlet来处理JSP,但是DispatcherServlet不具备查找和处理jsp的能力,会报错
  • 如果DispatcherServlet配置的是/,可以正常访问JSP

    • /是缺省匹配,优先级低于扩展名匹配(Tomcat里有JspServlet,路径是*.jsp
    • 必定是由Tomcat来处理JSP,Tomcat本身具备查找和处理JSP的能力,可以正常访问JSP

    完全路径匹配 > 目录匹配 > 扩展名匹配 > 缺省匹配

    /aa > /* > *.do > /

3.4. controller的配置
3.4.1 配置示例
package com.mingye.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.Servlet;

/*
    @Controller :
        1. 表示这个类是一个控制器,可以处理请求。
        2. spring会把这个类管理起来, 创建这个类的对象。
    RequestMapping :
        1. 表示方法的映射地址,当什么请求来的时候,会执行这个方法。
        2. 属性:
            value|path : 用来设置映射路径
            method : 用来设置请求方式,表示什么样的请求方式,才能执行这个方法。【默认是都支持!】
                RequestMethod.GET : 允许get请求到这里来
                RequestMethod.POST : 允许post请求到这里来
                    如果设置了post,页面还是用get请求过来,那么会报错:
                        Request method 'GET' not supported
            params : 用来要求请求一定要携带指定名称的参数
                params="username"`:必须提交了 名称为username的表单参数,才可以访问
                params="username=tom"`:必须提交了 名称为username、值为tom的表单参数,才可以访问
                params="username!=tom"`:提交了表单参数  名称为username、值不是tom, 才可以访问
        3. 这个注解可以打在方法身上,也可以打在类身上!
            3.1 在类身上写@RequestMapping,访问方法时,需要加上类上面的映射路径
            3.2 这样子做的好处主要是为了和其他的模块进行区分。有前缀的划分。
 */
@Controller
@RequestMapping("/controller01")
public class Controller01  {


    @RequestMapping(value = "/sayHi04", method = RequestMethod.GET , params = "username")
    public String sayHi04(){
        System.out.println("调用了Controller01的sayHi04方法~!~");
        return "success";
    }
}
3.4.2 配置说明

@RequestMapping注解 , 通常用在Controller里,用于设置访问路径

  • 注解语法
@RequestMapping(
	value="访问路径",
    method=请求方式,
    params="请求参数"
)
  • 常用属性:
    • value/path:访问路径,即:什么路径能够访问到这个方法
    • method:请求方式,即:什么请求方式能够访问这个方法。从枚举RequestMethod中取值
      • RequestMethod.POST:必须是POST方式,才可以访问到
      • RequestMethod.GET:必须是GET方式,才可以访问到
    • params:请求参数,即:请求携带了什么样的参数能够访问这个方法(了解)
      • params="username":必须提交了 名称为username的表单参数,才可以访问
      • params="username=tom":必须提交了 名称为username、值为tom的表单参数,才可以访问
      • params="username!=tom":提交了表单参数 名称为username、值不是tom, 才可以访问
  • 如果注解用在Controller类上
    • 表示设置访问路径的一级目录,要和方法上的路径组装成访问路径。用于模块化管理,例如:
      • 类上有注解@RequestMapping("/user")
      • 类里方法上有注解@RequestMapping("/save")
      • 那么方法的访问路径是:/user/save

第二章-获取请求数据【重点】

知识点-请求参数的绑定

1.目标

  • 掌握请求参数的获取

2.路径

  1. 绑定机制
  2. 支持的数据类型
  3. 使用要求

3.讲解

  • 绑定机制

    表单提交的数据都是key=value格式的(username=zs&password=123), SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的(要求:提交表单的name和方法的参数的名称是相同的)

<form action="">
    用户名:<input type="text" name="username"/>
    密码: <input type= "password" name="password"/>
    <input type="submit"/>
</form>
public String register(String username , String password){


}

//======================================================

class User{
    
    private String username;
    private String password;
    
}

public String register02(User user){


}
  • 支持的数据类型

    ​ 基本数据类型和字符串类型

    ​ 实体类型(JavaBean)

    ​ 集合数据类型(List、map集合等)

  • 使用要求

    • 如果是基本类型或者 String 类型: 要求我们的参数名称必须和controller中方法的形参名称保持一致。 (严格区分大小写) .

    • 如果是 对象 类型,或者它的关联对象: 要求表单中参数名称和对象类的属性名称保持一致

    • 如果是集合类型,有两种方式:

      • 第一种:要求集合类型的请求参数必须在对象类 中。在表单中请求参数名称要和 对象类中集合属性名称相同。给 List 集合中的元素赋值, 使用下标【】。给 Map 集合中的元素赋值, 使用键值对。
      • 第二种:接收的请求参数是 json 格式数据。需要借助一个注解实现 @RequestBody

4.小结

  1. 绑定机制

SpringMVC的参数绑定过程是把表单提交的请求参数,作为controller里面方法的参数进行绑定的。

  1. 支持的数据类型 :

​ 基本数据类型和字符串类型

​ 实体类型(JavaBean)

​ 集合数据类型(List、map集合等)

  1. 使用要求: 名字需要一样

知识点-获取请求参数

1.目标

  • 掌握简单参数的获取

2.路径

  1. 基本类型和String
  2. 对象类型
  3. 数组
  4. 对象包含属性

3.讲解

3.1 基本类型和String 【重点】
  • 说明

    • 客户端提交的表单参数名称, 和Controller里方法参数名称相同
    • SpringMVC会自动绑定同名参数,并自动转换类型
  • 页面

  • index.jsp

<h2>提交简单的参数:</h2>
<form action="/requestSimpleParam" method="post">
    用户名:<input type="text" name="username"/><br/>
    密  码:<input type="text" name="password"/><br/>
    年  龄:<input type="text" name="age"/><br/>
    <input type="submit"/>
</form>

  • success.jsp
<%--
  Created by IntelliJ IDEA.
  User: xiaomi
  Date: 2021/9/29
  Time: 11:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>这是成功的页面~!~</h2>
</body>
</html>


  • controller
package com.mingye.controller;

import com.mingye.bean.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;

@Controller
public class Controller01 {

    /*
        获取简单的参数:
            要求:
                1. 方法的参数名字必须和页面的form表单中的name属性的值 一样!
                    用户名:<input type="text" name="username"/>
     */
    @RequestMapping("/requestSimpleParam")
    public String requestSimpleParam(String username, String password , int age){
        System.out.println("username = " + username);
        System.out.println("password = " + password);
        System.out.println("age = " + age);

        return "success";
    }

}

3.2 对象类型 【重点】

SpringMVC会帮我们自动把表单参数,封装成对象,但是要求:

  • 客户端提交的表单参数名称,必须和JavaBean的属性名一样!
  • Pojo(User)
package com.mingye.bean;

import lombok.Data;

@Data
public class User {
    private String username;
    private String password;
    private int age;
}
  • 前端页面
<h2>提交对象的参数:</h2>
<form action="/requestObjectParam">
    用户名:<input type="text" name="username"/><br/>
    密  码:<input type="text" name="password"/><br/>
    年  龄:<input type="text" name="age"/><br/>
    <input type="submit"/>
</form>
  • controller
package com.mingye.controller;

import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;

@Controller
public class Controller01 { 
    /*
        获取对象参数:
            要求:
                1. 页面提交上来的form表单的name属性值必须和JavaBean的属性名字一样!
                    用户名:<input type="text" name="username"/>

                    public class User {
                        private String username;
                    }
     */
    @RequestMapping("/requestObjectParam")
    public String requestObjectParam(User user){
        System.out.println("user = " + user);
        return "success";
    }

}
3.3 数组【了解】

注:只能2接前端多个参数(一个名字对应多个值),不能用List集合。确实需要List集合接收时,使用包装user.list

  • 页面
<h2>提交数组的参数:</h2>
<form action="/requestArrayParam">
    请选择您的爱好:<br/>
        <input type="checkbox" name="hobby" value="smoke"/>抽烟
        <input type="checkbox" name="hobby" value="drink"/>喝酒
        <input type="checkbox" name="hobby" value="firehead"/>烫头<br/>
    <input type="submit"/>
</form>


  • Controller01
package com.mingye.controller;

import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;

@Controller
public class Controller01 {
      /*
        获取数组参数:
            要求:
                1. 页面上的表单项,name属性值必须一样!
                2. 方法参数的名字必须和name属性的值一样!
     */
    @RequestMapping("/requestArrayParam")
    public String requestArrayParam(String [] hobby){
        System.out.println("hobby=" + Arrays.toString(hobby));
        return "success";
    }
}

4.小结

  1. 请求参数类型是简单(基本,String)类型

    • 方法的形参和请求参数的name一致就可以
  2. 请求参数类型是pojo对象类型

    • 形参就写pojo对象
    • pojo的属性必须和请求参数的name一致就可以
  3. 提交数组,只能用数组接收,多个参数的name属性名一致,参数要与controller中的参数名一致。

知识点-细节处理和特殊情况

1.目标

  • 掌握乱码处理和自定义类型转换器

2.路径

  1. 请求参数乱码处理
  2. 自定义类型转换器
  3. 使用 ServletAPI 对象作为方法参数

3.讲解

3.1 请求参数乱码

如果请求参数或者响应中有中文就会乱码。在web阶段,我们通过一个自定义的过滤器实现了统一乱码解决

req.setCharacterEncoding(“utf-8”)

resp.setContentType(“text/html;charset=utf-8”);

但是在springMVC中,处理post请求时,由于它的运作机制,DispatcherServlet很早就已经把数据(参数)拿出来了,此时的数据是乱码的,这个时候你在方法中设置了编码也没用了,所以只能用过滤器了,因为过滤器会先拦截请求,早于servlet。

现在SpringMVC本身 ,也给我们提供了一个过滤器CharacterEncodingFilter,用于解决乱码问题 。 只有在post请求才会有中文乱码,如果tomcat > 8.5的版本,那么tomcat已经帮助修复了get请求的中文乱码。

如果使用了tomcat7的插件来跑项目, get请求还是会有乱码的!需要配置一下下!

  • 在web.xml里面配置编码过滤器
	<!--配置字符编码过滤器-->
	<filter>
		<filter-name>char</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

		<!--指定使用UTF-8的编码 , encoding是固定写法-->
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>char</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  • 如果使用了tomcat7的插件,get请求会出现中文乱码,那么可以这么解决
  <build> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.tomcat.maven</groupId>  
        <artifactId>tomcat7-maven-plugin</artifactId>  
        <version>2.2</version>  
        <configuration> 
          <!-- 指定端口 -->  
          <port>82</port>  
          <!-- 请求路径 -->  
          <path>/</path>

          <!--配置编码-->
          <uriEncoding>utf-8</uriEncoding>
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
3.2 自定义类型转换器

默认情况下,SpringMVC已经实现一些数据类型自动转换。 内置转换器全都在: org.springframework.core.convert.support 包下 ,如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。

)

3.2.1 场景
  • 页面
<h2>提交包含日期的参数:</h2>
<form action="/requestDateParam">
    用户名:<input type="text" name="username"/><br/>
    密  码:<input type="text" name="password"/><br/>
    出生日期:<input type="text" name="birthday"/><br/>
    <input type="submit"/>
</form>

  • User04
package com.mingye.bean;

import lombok.Data;

import java.util.Date;

@Data
public class User04 {
    private String username;
    private String password;
    private Date birthday;
}

  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;


@Controller
public class Controller01 {

     /*
        获取日期格式的数据
     */
    @RequestMapping("/requestDateParam")
    public String requestDateParam(User04 user04){
        System.out.println("user04 = " + user04);
        return "success";
    }

}
  • 报错
3.2.2 自定义类型转换器

步骤:

  1. 创建一个类实现Converter 接口
  2. 配置类型转换器

实现:

  • 定义一个类,实现 Converter 接口

    该接口有两个泛型,S:表示接受的类型, T:表示目标类型(需要转的类型)

package com.mingye.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


/*
    自定义日期格式转换器
        1. 定义类,实现接口Converter
            里面有两个泛型: S : 表示的是源数据的类型 , T: 表示的是目标数据的类型
        2. 实现方法convert
 */
public class DateConverter implements Converter<String , Date> {

    /**
     *
     * @param source 从页面接收到的数据
     * @return 转化出来的日期对象。
     */
    public Date convert(String source) {
        try {
            System.out.println("来到我们的日期转化器了:" + source);
            //1. 定义SimpleDateFormat对象
            SimpleDateFormat sf =null ;
            if(source .contains("-")){
                sf = new SimpleDateFormat("yyyy-MM-dd");
            }else if(source.contains("/")){
                sf = new SimpleDateFormat("yyyy/MM/dd");
            }
            //2. 转化
            return sf.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

  • 在springmvc.xml里面配置转换器

    spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去

    <!--2. 注解驱动-->
        <mvc:annotation-driven conversion-service="cs"/>

        <!--
            5. 配置日期格式转换器
                5.1 配置转换工厂对象
                5.2 给它里面的集合    converters 注入我们自己的类型转换器!
        -->
        <bean id="cs" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <bean class="com.mingye.converter.DateConverter"/>
            </property>
        </bean>

第三章-常用注解【重点】

知识点-常用的注解

1. 目标

  • 掌握常用注解的使用

2. 路径

  1. @RequestParam 【重点】
  2. @RequestBody 【重点】
  3. @PathVariable 【重点】
  4. @RequestHeader【重点】
  5. @CookieValue【了解】

3. 讲解

3.0 环境准备
3.0.1 导入依赖
  <dependencies> 
    <!--springmvc-->  
    <dependency> 
      <groupId>org.springframework</groupId>  
      <artifactId>spring-webmvc</artifactId>  
      <version>5.0.2.RELEASE</version> 
    </dependency>  
    <!--jsp-api-->  
    <dependency> 
      <groupId>javax.servlet.jsp</groupId>  
      <artifactId>javax.servlet.jsp-api</artifactId>  
      <version>2.3.1</version>  
      <scope>provided</scope> 
    </dependency>  
    <!--servlet-api-->  
    <dependency> 
      <groupId>javax.servlet</groupId>  
      <artifactId>javax.servlet-api</artifactId>  
      <version>3.1.0</version>  
      <scope>provided</scope> 
    </dependency>  
    <dependency> 
      <groupId>org.projectlombok</groupId>  
      <artifactId>lombok</artifactId>  
      <version>1.18.18</version> 
    </dependency>


    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.6</version>
    </dependency>
</dependencies>
3.0.2 定义两个页面
  • index.jsp
<%--
  Created by IntelliJ IDEA.
  User: xiaomi
  Date: 2021/9/10
  Time: 8:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>这是首页~!</h2>
</body>
</html>
  • success.jsp
<%--
  Created by IntelliJ IDEA.
  User: xiaomi
  Date: 2021/9/10
  Time: 8:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>这是成功的页面~!</h2>

</body>
</html>

3.0.3 springmvc.xml
<?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 http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

            <context:component-scan base-package="com.mingye"/>

            <mvc:annotation-driven/>

            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/"/>
                <property name="suffix" value=".jsp"/>
            </bean>

            <mvc:default-servlet-handler/>
</beans>
3.0.4 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<!--配置前端控制器 DispatcherServlet-->
		<servlet>
			<servlet-name>dispatcher</servlet-name>
			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

			<init-param>
				<param-name>contextConfigLocation</param-name>
				<param-value>classpath:springmvc.xml</param-value>
			</init-param>

			<load-on-startup>1</load-on-startup>
		</servlet>

		<servlet-mapping>
			<servlet-name>dispatcher</servlet-name>
			<url-pattern>/</url-pattern>
		</servlet-mapping>

	<!--springmvc已经定义好了过滤器,可以帮助我们解决post请求,中文乱码的问题,我们只需要配置即可-->
		<filter>
			<filter-name>char</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>char</filter-name>
			<url-pattern>/*</url-pattern>
		</filter-mapping>
</web-app>
3.1 @RequestParam【重点】
3.1.1 使用说明
  • 作用:

    1. 可以对浏览器请求做出参数上的要求,要求一定要有指定名字的参数,如果没有,就报错!
    2. 可以把请求提交上来的参数赋值给方法的形参。
  • 属性

    value: 要求携带的参数名字
    required:请求参数中是否必须提供此参数。 默认值: true。表示必须提供,如果不提供将报错。

    defaultValue:默认值

3.1.2 使用示例
  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {


     /*
        @RequestParam:
            作用: 要求客户端来访问的时候,一定要携带指定名称的参数,否则报错!
            步骤:
                1. 在方法参数的前面打注解 @RequestParam
             属性:
                name|value : 用来指定携带的参数名称,如果不指定,那么就以参数名为参考标准。
                required: 表示是否一定要携带参数,默认值是true,
                defaultValue: 默认值
     */
    @RequestMapping("/requestParam")
    public String requestParam(@RequestParam(value="abc" , required = false , defaultValue = "张三") String username , @RequestParam String password){
        System.out.println("username = " + username);
        System.out.println("password = " + password);
        return "success";
    }
}

@RequestParam 只能用于接收 url 的传参 ?name=xxx, form表单的提交。

无法接收提交的json数据(contentType=application/json)

3.2 @RequestBody【重点】
3.2.1 使用说明
  • 作用

    1. 用于获取请求体内容。 直接使用得到是 key=value&key=value…结构的字符串。【不常用】
    2. 把获得json类型的数据转成JavaBean对象(后面再讲)【推荐】

    **注意: get 请求方式不适用。 **

  • 属性

    required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false, get 请求得到是 null。

  • @RequestBody 不能使用get请求, 在Controller的方法参数里,@RequestBody它只能出现一次!
  • 匹配json数据的获取,例如:request.getInputStream()
3.2.2 使用实例
  • index.jsp 页面 追加以下内容
<h2>使用@RequestBody获取请求体:</h2>
<form action="/requestBody01" method="post">
    用户名: <input type="text" name="username"/><br/>
    密码: <input type="text" name="password"/><br/>
    <input type="submit">
</form>
  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {


   /*
        @RequestBody
            作用:
                1. 可以获取表单提交上来的请求体,只有post请求才有请求体,get请求是没有请求体【不常用】
                    拿到的是一个字符串:  username=admin&password=123456;
                2. 可以接收页面提交上来的json数据,封装到JavaBe里面【常用】
            步骤:
                1. 方法参数的前面打上注解 @RequestBody,springmvc就会把请求体赋值给方法的参数。
     */
    @RequestMapping("/requestBody01")
    public String requestBody01(@RequestBody String body) throws UnsupportedEncodingException {
        System.out.println("body = " + body);
    }

        /*
            页面提交中文的时候,默认情况下,浏览器会对内容进行编码,使用URLEncoder.encode("张三","utf-8");
                6张三7 ----URLEncoder.encode("张三","utf-8")-----6%E5%BC%A0%E4%B8%897

            如果我们希望看到正常的张三:
                1. 必须要设置过滤器,真正的解决中文乱码的问题。
                2. 对这份数据解码即可:
                6%E5%BC%A0%E4%B8%897 ----------URLDecoder.decode("6%E5%BC%A0%E4%B8%897", utf-8);
         */
        String data = URLDecoder.decode(body, "utf-8");
        System.out.println("data = " + data);

        return "success";
    }
}
3.2.3 接收json数据
需求描述
  • 客户端发Ajax请求,提交json格式的数据
  • 服务端接收json格式的数据,直接封装成User对象
前提条件
  • pom.xml中添加jackson的依赖:
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.6</version>
</dependency>
  • springmvc.xml中,增加配置静态资源的处理

因为发请求,需要ajax的支持。

<!--配置静态资源的处理-->
<mvc:default-servlet-handler/>
需求实现
  • index.jsp 添加以下内容
<h2>使用@RequestBody来获取json数据</h2><input type="button" οnclick="sendJSON()" value="点我发送JSON数据"/><script src="js/axios-0.18.0.js"></script><script>    function sendJSON(){        //1. 定义一份json数据        var data = {"username":"admin" , "password":"123456"};        //2. 使用axios发起异步请求        axios.post("/requestBody02" , data);    }</script>
  • Controller01
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {


  /*
        @RequestBody:
            接收页面提交上来的json数据,封装到JavaBean对象身上。
           步骤:
                1. 前端页面必须提交的是一份json数据

                2. 添加进来jackson-databind的依赖
                    如果不加依赖,会报错: 415 Unsupported Media Type

                3. 定义一个JavaBean,属性名字不能乱写,必须和json里面的KEY一样。

                4. 在Controller方法参数的前面加上注解@RequestBody
                    如果不加,那么得到的是默认值!
     */
    @RequestMapping("/requestBody02")
    public String requestBody02(@RequestBody User user ) {
        System.out.println("user = " + user);
        return "success";
    }

}
3.3 @PathVariable【重点】
3.3.1 使用说明
  • 作用:

    用于截取请求地址(url)里面的某些部分的数据。这个需要配合RestFul风格来说明

    以前删除用户: localhost:82/deleteUser?id=3restFul :  localhost:82/delete/3
    
  • 属性:

    value: 用于指定 url 中占位符名称。
    required:是否必须提供占位符。

  • 场景:获取路径中的参数,与restful编程风格一起,通常微服架构中使用
3.3.2 使用实例
  • index.jsp 页面添加以下内容
<h2>使用@PathVariable来获取地址中的参数</h2>
<a href="/delete/1">点我发请求</a>
<a href="/delete02/30/40">点我发请求2</a>
  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {

     /*
        现在以 按照id来删除用户举例:
            以前的写法:  localhost:82/delete?id=1
            restFul:  localhost:82/delete/1

         @PathVariable:
            作用: 用来截取地址栏中的参数,赋值给方法的形参
            步骤:
                1. 在映射地址里面使用 {占位符名字} 来占位,表示匹配这个位置的数据
                2. 在方法参数的前面加上注解 @PathVariable("占位的名字")
             属性:
                name |  value : 用来指定|设置 占位符的名称。
                   如果name和value不写,只有一种情况可以不写,就是占位符的名字和方法的参数名字一样!
     */

    @RequestMapping("/delete/{id}")
    public String pathVariable(@PathVariable(value="id") int id) {
        System.out.println("id = " + id);
        return "success";
    }

    @RequestMapping("/delete02/{id}/{id2}")
    public String pathVariable02(@PathVariable int id , @PathVariable int id2) {
        System.out.println("id = " + id);
        System.out.println("id2 = " + id2);
        return "success";
    }
}
3.4 @RequestHeader【重点】
3.4.1 使用说明
  • 作用:
    获取指定名字的请求头数据,赋值给方法参数。
  • 属性:
    value:提供消息头名称
    required:是否必须有此消息头 , 默认值是true
  • 从请求头中获取参数,鉴权(token 畅购open auth 2.0 jwt token) Authorization
3.4.2 使用实例
  • index.jsp 页面 添加以下内容
<h2>使用@ReqeustHeader来获取请求头的数据</h2>
<a href="/requestHeader">点我发请求</a>
  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {


    /*
        @RequestHeader:
            作用: 用来获取指定名称的请求头数据,赋值给方法的参数
     */
    @RequestMapping("/requestHeader")
    public String requestHeader(@RequestHeader("User-Agent") String data) {
        System.out.println("data = " + data);
        return "success";
    }
}
3.5 @CookieValue【了解】
3.5.1 使用说明
  • 作用:

    用于把指定 cookie 名称的值传入控制器方法参数。

  • 属性:

    value:指定 cookie 的名称。
    required:是否必须有此 cookie, 默认值是:true

3.5.2 使用实例
  • index.jsp 页面添加以下内容
<h2>使用@CookieValue来获取Cookie的值</h2>
<a href="/cookieValue">点我发请求</a>


  • Controller01.java
package com.mingye.controller;

import com.mingye.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/*
    常用的注解:
 */
@Controller
public class Controller01 {




    /*
        @CookieValue
            作用: 用来获取指定名称的cookie的值,赋值给方法的形参。
            属性:
                name&value : 指定cookie的名字!

           JESSIONID:
                1. 这是session作用域的id的名称,它会存放到cookie里面去。
                2. 当我们打开首页的时候,访问的是index.jsp  ----背后会被翻译成========> Servlet
                3. 在这个翻译成的servlet里面,它会创建session对象,并且把session的地址存放到cookie里面去。
                    存放的cookie的KEY 叫做: JSESSIONID.
     */
    @RequestMapping("/cookieValue")
    public String cookieValue(@CookieValue("JSESSIONID") String data) {
        System.out.println("data = " + data);
        return "success";
    }

}

4. 小结

  1. 这几个注解都使用作用在方法的参数上,不是写在方法上。他们或多或少都是对客户端提交的数据有这样或者那样的要求
  2. @RequestParam : 要求客户端必须要携带指定的参数。
  3. @RequestBody: 要求必须有请求体,一般它是作用于 页面提交上来的json数据,转化成 javabean对象
  4. @PathVariable : 路径变量,配合RestFul风格使用,用于截取地址里面的数据
  5. @RequestHeader: 用来获取的指定的请求头数据,赋值给方法形参
  6. @CookieValue: 用来获取的cookie数据,赋值给方法的形参。

第四章-springMVC-纯注解方式

三个配置类

  1. AppConfig

    /*配置DishpatcherServlet*/
    public class AppConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        //用来配置除了SpringMVC之外的其他配置类: spring的配置类 、mybatis的配置类
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};
        }
    
        //用来配置SpringMVC的配置类是哪些!
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringmvcConfig.class};
        }
    
        //DispatcherServlet 映射路径是什么?
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
        //设置过滤器
        @Override
        protected Filter[] getServletFilters() {
            return new Filter[]{new CharacterEncodingFilter("utf-8")};
        }
    }
    
    
  2. SpringConfig

    暂时还用不到

  3. SpringmvcConfig

    @EnableWebMvc  // 启用MVC的功能,可以看成是相当于 注解驱动
    @ComponentScan("com.mingye")  //扫描包
    @Configuration //表示这是一个配置类
    public class SpringmvcConfig extends WebMvcConfigurerAdapter {
    
        // 用来配置视图解析器
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
    
            //1. 创建视图解析器对象
            InternalResourceViewResolver vr = new InternalResourceViewResolver();
    
            //2. 配置前缀和后缀
            vr.setPrefix("/");
            vr.setSuffix(".jsp");
    
            //3. 把视图解析器的对象,放到视图解析器注册器里面去
            registry.viewResolver(vr);
    
        }
    
        // 用来控制是否启用Tomcat里面的DefaultServlet
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }
    

注意事项

一、两种错误:namespace导错、没有xml约束

  1. 如果xml文件上方的namespace不小心导错了,会报错,比如错导了core

​ 会报以下错误,说:不认识cache相关的东西,就是因为错导了cache的命名空间。

  1. 命名空间导了,但是有的时候会出现约束没有导,也会报错

    如果约束没写,会报以下错误

二、Tomcat7依赖运行部分jar包不兼容

Tomcat7依赖运行会有一些jar包不兼容的情况,有冲突的jar都是按照这种办法处理,tomcat8以上版本就不会有这个问题了

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个网上书城项目采用了当前最流行的框架spring-springmvc-mybatis设计。这个项目旨在提供一个方便、快捷的购书平台,用户可以通过该平台浏览、搜索并购买自己喜欢的图书。 在这个项目中,我们使用了Spring作为项目的核心框架,它提供了依赖注入和面向切面编程等功能,使得项目的开发更加简洁和易于维护。Spring MVC作为项目的Web框架,负责将用户的请求路由到对应的Controller,并负责视图的渲染和返回。而MyBatis则是作为持久层框架,将数据库的操作和Java代码的实现解耦,提供了灵活的SQL映射和缓存机制。 在这个网上书城项目中,我们设计了一套完整的功能模块:用户管理模块、图书管理模块、订单管理模块等。用户可以通过注册、登录等功能来进行用户管理,并可以在平台上对图书进行购买、收藏等操作。同时,平台还提供了搜索功能,用户可以根据图书的名称、作者等进行快速查找。 这个项目的设计更加便于扩展和维护,使用了分层架构,将业务逻辑、持久层和展示层进行了有效的分离。同时,也采用了面向接口编程的思想,降低了模块之间的耦合度,提高了代码的复用性和可测试性。 总之,这个网上书城项目基于spring-springmvc-mybatis框架的设计,充分利用了各自的优势,提供了一个高效、稳定和易于维护的购书平台。期望能为用户提供良好的购书体验,并为图书销售行业的发展做出贡献。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值