SpringMVC(一)之环境搭建、参数绑定、常用注解

服务器端分成三层框架

在这里插入图片描述

三层架构

  1. 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
  2. 业务层:处理公司具体的业务逻辑的
  3. 持久层:用来操作数据库的

表现层什么功能?

主要和浏览器进行数据的交互
浏览器向表现层发送请求参数
表现层向浏览器相应结果

MVC模型(属于表现层)

M model 模型 JavaBean的一个对象
V View 视图 JSP
C Controller 控制器 Servlet ,用来接收用户的请求,整个流程的控制器。用来进行数据校验等。

SpringMVC(表现层框架)在三层架构的位置
SpringMVC在三层架构的位置

在这里插入图片描述

入门程序之需求分析

在这里插入图片描述
1 搭建开发的环境
2 编写入门的程序

1 搭建开发的环境

创建maven骨架图
在这里插入图片描述
解决maven创建过慢
在这里插入图片描述
加入键值对
archetypeCatalog
internal

在main目录下新建Java resource把目录结构补全并设为根目录和资源目录
在这里插入图片描述

导入坐标 依赖

<spring.version>5.0.2.RELEASE</spring.version>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

配置前端控制器
在webapp中web.xml配置

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

  <!--任何请求都会拦截-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

创建配置文件
在这里插入图片描述

部署在Tomcat上
在这里插入图片描述

2 编写入门的程序

编写首页

index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>菜鸡</h3>
    <a href="hello">入门程序</a>
</body>
</html>

实现点击链接后进入到控制器类并执行控制器类中的方法,要执行方法,必须有控制器的对象
所以在HelloController 类上加上注解@Controller,可以交给SpringIOC容器进行管理
接着在springmvc.xml中配置,扫描注解

<!--先开启注解扫描,导入Context命名空间,在HelloController上加注解-->
<context:component-scan base-package="cn.tju"></context:component-scan>

需要执行方法,所以要给方法加上 @RequestMapping(path="/hello")注解
意思是:加注解(请求-映射注解)后,相应的请求对应的方法就执行,可以设置请求的路径
注意方法返回值是字符串,在springmvc框架中默认是Jsp文件的名字,所以此方法会返回succsee.jsp
此时需要到springmvc.xml中继续配置

<!--在方法一返回success,就去配置目录,找对应配置的后缀名文件-->
    <!--配置视图的解析器对象-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--文件所在的目录-->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <!--文件的后缀名-->
        <property name="suffix" value=".jsp"></property>
    </bean>
最后一定要开启注解的支持
 <!--开启springMVC框架注解的支持-->
    <mvc:annotation-driven/>

HelloController.java

@Controller
public class HelloController {

    @RequestMapping(path="/hello")
    public String sayHello(){
        System.out.println("hello springMvc");
        return "success";
    };


}

springmvc.xml

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

    <!--先开启注解扫描,导入Context命名空间,在HelloController上加注解-->
    <context:component-scan base-package="cn.tju"></context:component-scan>


    <!--在方法一返回success,就去配置目录,找对应配置的后缀名文件-->
    <!--配置视图的解析器对象-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--文件所在的目录-->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <!--文件的后缀名-->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--开启springMVC框架注解的支持-->
    <mvc:annotation-driven/>

</beans>

此时有一个问题就是配置文件(springmvc.xml)springmvc没法读取这个配置文件
需要配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

入门流程总结

1 启动服务器,加载一些配置文件

原来发送请求才创建servlet
现在服务器已启动就创建servlet(dispatcherServlet)对象

 <!--启动服务器就创建-->
<load-on-startup>1</load-on-startup>
servlet对象一创建就加载类路径下的配置信息(springmvc.xml)
<init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
</init-param>

配置信息配了哪些信息?
注解扫描,把类变创建成对象

<!--先开启注解扫描,导入Context命名空间,在HelloController上加注解-->
    <context:component-scan base-package="cn.tju"></context:component-scan>

创建注解解析器对象

 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

整体注解生效开启

 <!--开启springMVC框架注解的支持-->
    <mvc:annotation-driven/>

2 发送请求,后台处理请求

通过index.jsp中的超链接发请求

<a href="hello">入门程序</a>

在web.xml中
servlet(dispatcherServlet)拦截所有的请求
dispatcherServlet前端控制器,指挥的中心,找到对应注解配置路径的方法
方法执行完,控制台看到输出,返回“success”,前端控制器知道了返回“success”
dispatcherServlet前端控制器找视图解析器对象InternalResourceViewResolver,通过其中配置的位置,和后缀名,找到success.jsp返回给servlet
servlet显示页面,返回结果

在这里插入图片描述

入门案例中使用的组件介绍

springmvc执行流程原理图
在这里插入图片描述

springmvc这个框架基于组件方式执行流程

1 客户端发送一个请求,请求先到DispatcherServlet前端控制器(指挥中心)
2 然后找处理器映射器HandlerMapping :作用,通过请求路径找到Controller类中对应的方法返回

比如以上例子,前端请求路径<a href="hello">,在方法上配置注解@RequestMapping(path="/hello")
HandlerMapping就是通过请求找对应的类HelloController对应方法sayHello()返回
3 向前端控制器返回对应的类的一个方法

前端控制器不能执行,只是起到一个中转的作用
4找处理器适配器 HandlerAdapter
处理器是指对应类Controller的对应方法
适配器对于任何类(任何Controller)最终都由适配器会执行对应的方法
5由适配器执行最终的方法
6 返回视图页面 “success”也就是success.jsp
7 向前端控制器返回这个页面success.jsp
8 前端控制器找视图解析器ViewResolver
9 视图解析器实现跳转到jsp页面
10 返回结果
11 响应回去

RequestMapping注解

作用:是建立请求URL和处理方法之间的对应关系

RequestMapping源码图
在这里插入图片描述
RequestMapping注解可以放到方法上,也可以放到类上

放到方法上,之前的例子就是
@RequestMapping(path="/hello")
public String sayHello(){

如果请求是,分为一级目录/二级目录
/user/hello
放到类上相当于一级目录

eg
index.jsp

<a href="user/testRequestMapping">RequestMapping</a>

HelloController.java,其中@RequestMapping("/user")同时放在方法上和类上

@Controller
@RequestMapping("/user")
public class HelloController {

    /**
     * RequestMapping注解
     * @return
     */
    @RequestMapping(path="/testRequestMapping")
    public String testRequestMapping(){
        System.out.println("测试RequestMapping注解。。。。");
        return "success";
    }
}

RequestMapping注解的属性

path value属性
@AliasFor("path")
String[] value() default {};

	
@AliasFor("value")
String[] path() default {};

因为属性上互为别名,所以path和value属性的作用是相同的,都是指映射的路径

method 属性
RequestMethod[] method() default {};

指定可以接收什么的请求方式
用一个RequestMethod数组赋值
RequestMethod是一个枚举类

public enum RequestMethod {

	GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

}

eg

@RequestMapping(path="/testRequestMapping",method={RequestMethod.POST} )
    public String testRequestMapping(){
        System.out.println("测试RequestMapping注解。。。。");
        return "success";
    }
params 属性

String[] params() default {};
赋值于String数组
用于指定限制请求参数的条件,它支持简单的表达式,要求参数的key和value必须和表达式配置的一摸一样

指定请求必须传一个username属性的参数

 @RequestMapping(path="/testRequestMapping",params={"username"})
    public String testRequestMapping(){
        System.out.println("测试RequestMapping注解。。。。");
        return "success";
    }
<a href="user/testRequestMapping?username=hha">RequestMapping</a>

则可以跳转

指定一组key和value

@RequestMapping(path="/testRequestMapping",params={"username=heihei"})
    public String testRequestMapping(){
        System.out.println("测试RequestMapping注解。。。。");
        return "success";
    }
<a href="user/testRequestMapping?username=heihei">RequestMapping</a>
headers属性

String[] headers() default {};
用于指定限制请求消息头的条件,也就是说发送的请求中必须包含请求头

 @RequestMapping(path="/testRequestMapping",params={"username=heihei"},headers ={"Accept"})
    public String testRequestMapping(){
        System.out.println("测试RequestMapping注解。。。。");
        return "success";
    }

请求头
在这里插入图片描述

请求参数的绑定

客户端传请求的时候带有参数,作为服务器一定要拿到参数,这个过程叫做参数绑定

1 绑定机制

表单提交参数都是一组键值对
username=hehe&password=123
这组键值对传过来

如果表单提交名称和方法参数是一模一样的话sayHello(String username,String password)
mvc框架就自动的会把请求传的值赋值到参数上

  1. 表单提交的数据都是k=v格式的 username=haha&password=123
  2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
  3. 要求:提交表单的name和参数的名称是相同的

2 支持的数据类型

  1. 基本数据类型和字符串类型
  2. 实体类型(JavaBean)
  3. 集合数据类型(List、map集合等)

例子
param.jsp

<html>
<head>
    <title>Title</title>
</head>
<body>
<%--请求参数的绑定--%>
<a href="param/testParam?username=hehe">请求参数绑定</a>
</body>
</html>

ParamController.java

/**
 * 请求参数绑定
 */
@Controller
@RequestMapping("/param")
public class ParamController {
    /**
     * 请求参数绑定入门
     * @return
     */
    @RequestMapping("testParam")
    public String testParam(String username){
        System.out.println("执行了。。。。");
        System.out.println(username);
        return "success";
    }
}

结果
执行了。。。。
hehe

如果把参数封装到一个JavaBean中

前端使用表单传值
表单中的name属性应该和JavaBean中属性是一致的,因为springmvc会通过name找JavaBean的set方法,给JavaBean属性赋值

<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"/><br/>
    密码:<input type="text" name="password"/><br/>
    金额:<input type="text" name="money"/><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

封装的JavaBean实体类Account

public class Account implements Serializable{
    private String username;
    private String password;
    private Double money;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", money=" + money +
                '}';
    }
}

后端的控制器

/**
 * 请求参数绑定
 */
@Controller
@RequestMapping("/param")
public class ParamController {


    /**
     * 请求参数把数据封装到JavaBean类中,提交的表单数据默认就封装到account对象中
     * @return
     */
    @RequestMapping("/saveAccount")
    public String saveAccount(Account account){
        System.out.println("执行了222。。。。");
        System.out.println(account);
        return "success";
    }
}

结果
执行了222。。。。
Account{username=‘hehe’, password=‘200’, money=1000.0}

如果封装的实体类的属性有引用类型
多了user属性

public class Account implements Serializable{
    private String username;
    private String password;
    private Double money;
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}
public class User implements Serializable{
    private String uname;
    private  Integer age;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", age=" + age +
                '}';
    }
}

对于新添加的input的name此时和account里user类的属性一致

<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"/><br/>
    密码:<input type="text" name="password"/><br/>
    金额:<input type="text" name="money"/><br/>
    <%--name此时指account里user类的属性--%>
    用户姓名:<input type="text" name="user.uname"/><br/>
    用户年龄:<input type="text" name="user.age"/><br/>
    <input type="submit" value="提交">

后端控制器

@Controller
@RequestMapping("/param")
public class ParamController {


    /**
     * 请求参数把数据封装到JavaBean类中,提交的表单数据默认就封装到account对象中
     * @return
     */
    @RequestMapping("/saveAccount")
    public String saveAccount(Account account){
        System.out.println("执行了222。。。。");
        System.out.println(account);
        return "success";
    }
}

结果
执行了222。。。。
Account{username=‘111’, password=‘111’, money=11.0, user=User{uname=‘11’, age=111111}}

配置解决中文乱码的过滤器

只需要在web.xml中配置一个过滤器

<web-app>
................
  <!--配置解决中文乱码的过滤器-->
  <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>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

请求参数绑定集合类型

public class Account implements Serializable{
    private String username;
    private String password;
    private Double money;
 

    private List<User> list;
    private Map<String,User> map;

   .................
}

前端表单

<%--把数据封装到Account类中,类中存在集合list和map--%>
<form action="param/saveAccount" method="post">
姓名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
金额:<input type="text" name="money"/><br/>

<%--把这组数据存放到user对象里去,再把user对象存放到list中去--%>
用户姓名:<input type="text" name="list[0].uname"/><br/>
用户年龄:<input type="text" name="list[0].age"/><br/>
    <%--把这组数据存放到user对象里去,再把user对象存放到map中去--%>
    用户姓名:<input type="text" name="map['one'].uname"/><br/>
    用户年龄:<input type="text" name="map['one'].age"/><br/>
<input type="submit" value="提交">

后台控制器

  /**
     * 请求参数把数据封装到JavaBean类中,提交的表单数据默认就封装到account对象中
     * @return
     */
    @RequestMapping("/saveAccount")
    public String saveAccount(Account account){
        System.out.println("执行了222。。。。");
        System.out.println(account);
        return "success";
    }

结果
执行了222。。。。
Account{username=‘hehe’, password=‘123’, money=200.0, list=[User{uname=‘ddd’, age=11}], map={one=User{uname=‘22’, age=111}}}

自定义类型转化器演示异常

页面提交的任何数据都是字符串类型,springMVC自动进行类型转换

正常情况下User由Date属性

public class User implements Serializable{
    private String uname;
    private  Integer age;

    private Date date;

......
}

前端页面

<%--自定义类型转化器--%>
<form action="param/saveUser" method="post">
<%--把这组数据存放到参数user对象里去--%>
用户姓名:<input type="text" name="uname"/><br/>
用户年龄:<input type="text" name="age"/><br/>
用户生日:<input type="text" name="date"/><br/>
<input type="submit" value="提交">

提交格式
在这里插入图片描述

后端控制器

  /**
     * 自定义类型转化器
     * @param user
     * @return
     */
    @RequestMapping("/saveUser")
    public String saveUser(User user){
        System.out.println("执行了33。。。。");
        System.out.println(user);
        return "success";
    }

结果正常输出
执行了33。。。。
User{uname=‘hehe’, age=200, date=Mon Nov 20 00:00:00 CST 2000}

错误日期格式
在这里插入图片描述

引入自动类型转换器
1 定义一个类,实现Converter接口,该接口由两个泛型

技巧:

ctrl+N 搜索Converter接口
ctrl + alt +B查看Converter接口的实现类

/**
 * 把字符串转换成日期
 */
public class StringToDateConverter implements Converter<String,Date> {

    /**
     *
     * @param source 传入进来的字符串的值
     * @return
     */
    @Nullable
    @Override
    public Date convert(String source) {
        //判断
        if(source == null){
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        //把字符串转换成日期
        try {
            return  df.parse(source);
        } catch (Exception e) {
           throw new RuntimeException("数据类型转换错误");
        }

    }
}

2 配置自定义类型转化器

<!-- 注册自定义类型转换器 -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.tju.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 开启Spring对MVC注解的支持 -->
<mvc:annotation-driven conversion-service="conversionService"/>

这样原来错误的日期格式后台就能获取了

获取servlet原生API

直接在控制器方法上加上参数就行

前端

<a href="param/testServlet">Servlet原生的API</a>

后台

  @RequestMapping("/testServlet")
    public String testServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行了44。。。。");
        System.out.println(request);


        HttpSession session = request.getSession();
        System.out.println(session);

        ServletContext servletContext = session.getServletContext();
        System.out.println(servletContext);
        System.out.println(response);
        return "success";
    }

结果
执行了44。。。。
org.apache.catalina.connector.RequestFacade@2c7e3c0a
org.apache.catalina.session.StandardSessionFacade@65aac915
org.apache.catalina.core.ApplicationContextFacade@491e0652
org.apache.catalina.connector.ResponseFacade@7b9d7c01

常用注解

1. RequestParam注解

  1. 作用:把请求中的指定名称的参数传递给控制器中的形参赋值
    解决,前端请求参数和后端控制器方法参数不一样封装不到数据的问题
  2. 属性
    • value:请求参数中的名称
    • required:请求参数中是否必须提供此参数,默认值是true,必须提供

前端请求

<a href="anno/testRequestParam?name=哈哈">RequestParam</a>

name和方法参数username不匹配所以使用RequestParam注解
后端控制器

/**
 * 常用的注解
 */
@Controller
@RequestMapping("/anno")
public class AnnoContrller {

    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(value ="name")  String username){
        System.out.println("执行了....");
        System.out.println(username);
        return "success";
    }
}

2. RequestBody注解

  1. 作用:用于获取请求体的内容,直接使用得到是key=value&key=value…结构的数据
    注意:get方法不可以,get方式是没有请求体,只有post请求有请求体

  2. 属性

    • required:是否必须有请求体,默认值是true

前端

<form action="anno/testRequestBody" method="post">
    用户姓名:<input type="text" name="username"/><br/>
    用户年龄:<input type="text" name="age"><br/>
    <input type="submit" value="提交"/>
</form>

后端

 /**
     * 获取到请求体的内容
     * @return
     */
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println("执行了。。。//");
        System.out.println(body);

        return "success";
    }

结果
执行了。。。//
username=111&age=1

3. PathVariable注解

  1. 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

  2. 属性

    • value:指定url中的占位符名称
  3. Restful风格的URL

    • 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
    • restful风格的URL优点
    • 结构清晰
    • 符合标准
    • 易于理解
    • 扩展方便

原来方式

UserController类
@RequestMapping() 也就是path="/user/save"
save方法
@RequestMapping() 也就是path="/user/upDate"
upDate方法
@RequestMapping() 也就是path="/user/findAll"
findAll方法

restful方式

不同的方法路径是同一个,发送请求地址都一样,但是根据请求方式不一样区分
@RequestMapping() 也就是path="/user post
save方法
@RequestMapping() 也就是path="/user" put
upDate方法
@RequestMapping() 也就是path="/user" get
findAll方法

当发送localhost:8080/user get,虽然请求地址一样但是根据请求方式找到findAll方法

如果还有一个相同请求方式的方法,通过占位符区分
path="/user/{id}" get
findById(id)

发送 localhost:8080/user/10 get 找到findById(id)方法
发送 localhost:8080/user 找到findAll方法

例子

前端
<a href="anno/testPathVariable/10">RequestParam</a>
后端
 /**
     * PathVariable注解
     * @param id
     * @return
     */
    @RequestMapping("/testPathVariable/{sid}")
    public String testPathVariable(@PathVariable(name="sid") String id){
        System.out.println("执行了。。。o ");
        System.out.println(id);

        return "success";
    }

结果
执行了。。。o
10

4 RequestHeader注解

  1. 作用:获取指定请求头的值
  2. 属性
    • value:请求头的名称
    • required:是否必须有此消息头

前端

<a href="anno/testRequestHeader">RequestHeader</a>

后台

 @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "Accept") String header){
        System.out.println("执行了。。。ob");
        System.out.println(header);

        return "success";
    }

结果
执行了。。。ob
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8

5. CookieValue注解

  1. 作用:用于获取指定cookie的名称的值
  2. 属性
    • value:cookie的名称

前端

<a href="anno/testCookieValue">testCookieValue</a>
后台
    @RequestMapping("/testCookieValue")
    public String testCookValue(@CookieValue(value ="JSESSIONID") String cookievalue){
        System.out.println("执行了。。。ob");
        System.out.println(cookievalue);

        return "success";
    }

结果
执行了。。。ob
C79AABC03C307D8E95DCF3EBDDF9E3F0

6. ModelAttribute注解

  1. 作用
    1. 出现在方法上:表示当前方法会在控制器方法执行前线执行。
    2. 出现在参数上:获取指定的数据给参数赋值。
  2. 应用场景
    1. 提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。

1. 修饰的方法有返回值

/**
* 作用在方法,先执行
* @param name
* @return
*/
@ModelAttribute
public User showUser(String name) {
System.out.println("showUser执行了...");
// 模拟从数据库中查询对象
User user = new User();
user.setName("哈哈");
user.setPassword("123");
user.setMoney(100d);
return user;
}


@RequestMapping(path="/updateUser")
public String updateUser(User user) {
System.out.println(user);
return "success";
}

2. 修饰的方法没有返回值

/**
* 作用在方法,先执行
* @param name
* @return
*/
@ModelAttribute
public void showUser(String name,Map<String, User> map) {
System.out.println("showUser执行了...");
// 模拟从数据库中查询对象
User user = new User();
user.setName("哈哈");
user.setPassword("123");
user.setMoney(100d);
map.put("abc", user);
}
/**
* 修改用户的方法
* @param cookieValue
* @return
*/
@RequestMapping(path="/updateUser")
public String updateUser(@ModelAttribute(value="abc") User user) {
System.out.println(user);
return "success";
}

7 SessionAttributes注解

  1. 作用:用于多次执行控制器方法间的参数共享,多次请求Session对话还在,此注解作用在类上
  2. 属性
    1. value:指定存入属性的名称
@Controller
@RequestMapping(path="/user")
@SessionAttributes(value= {"username","password","age"},types=
{String.class,Integer.class}) // 把数据存入到session域对象中
public class HelloController {
/**
* 向session中存入值
* @return
*/
@RequestMapping(path="/save")
public String save(Model model) {
System.out.println("向session域中保存数据");
model.addAttribute("username", "root");
model.addAttribute("password", "123");
model.addAttribute("age", 20);
return "success";
}
/**
* 从session中获取值
* @return
*/
@RequestMapping(path="/find")
public String find(ModelMap modelMap) {
String username = (String) modelMap.get("username");
String password = (String) modelMap.get("password");
Integer age = (Integer) modelMap.get("age");
System.out.println(username + " : "+password +" : "+age);
return "success";
}
/**
* 清除值
* @return
*/
@RequestMapping(path="/delete")
public String delete(SessionStatus status) {
status.setComplete();
return "success";
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值