SpringMVC ( 一 )


前言

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。
SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成
为最优秀的 MVC 框架。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持
RESTful 编程风格的请求。


一、MVC模型

MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职:

Model(模型):
通常指的就是我们的数据模型。作用一般情况下用于封装数据。
View(视图):
通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。
通常视图是依据模型数据创建的。

Controller(控制器)
是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。
它相对于前两个不是很好理解,这里举个例子:
例如:
我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等。
这时候表单输入要求年龄必须是 1~100 之间的整数。姓名和性别不能为空。并且把数据填充
到模型之中。
此时除了 js 的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做
的。
当校验失败后,由控制器负责把错误页面展示给使用者。
如果校验成功,也是控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求。


二、SpringMVC 概述

1.SpringMVC 在三层架构的位置

在这里插入图片描述

2.SpringMVC 的优势

1、清晰的角色划分:

  • 前端控制器(DispatcherServlet)
  • 请求到处理器映射(HandlerMapping)
  • 处理器适配器(HandlerAdapter)
  • 视图解析器(ViewResolver)
  • 处理器或页面控制器(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风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。


3.SpringMVC 和 Struts2 的优略分析

共同点:

  • 它们都是表现层框架,都是基于 MVC 模型编写的。
  • 它们的底层都离不开原始 ServletAPI。
  • 它们处理请求的机制都是一个核心控制器。

区别:

  • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter

  • Spring MVC 是基于方法设计的,而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所 以 Spring
    MVC 会稍微比 Struts2 快些。

  • Spring MVC 使用更加简洁,同时还支持 JSR303, 处理 ajax 的请求更方便
    (JSR303 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,就可以在需要校验的时候进行校验了。)

  • Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提 升,尤其是 struts2 的表单标签,远没有 html 执行效率高。


# 三、SpringMVC 入门 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200826215315773.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEyMDYyOTE=,size_16,color_FFFFFF,t_70#pic_center)

1.maven坐标

<?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.wjl</groupId>
  <artifactId>day32_springmvc_init</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>day32_springmvc_init Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <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>

  </dependencies>

  <build>
    <finalName>day32_springmvc_init</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

2.核心控制器

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>

3.编写控制器并使用注解配置

HelloController.java 代码如下:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(){
        System.out.println("Hello SpringMVC");
        return "success";
    }

    /**
     * 测试RestRequestMapping注解
     * @return
     */
    @RequestMapping(value = "/testRequestMapping" ,params = {"username"})
    public String testRequestMapping(String username){
        System.out.println(username);
        System.out.println("...testRequestMapping...");
        return "success";
    }

    /**
     * 测试RestRequestMapping注解
     * @return
     */
    @RequestMapping(value = "/testRequestMapping")
    public String testRequestMapping(){
        System.out.println("...testRequestMapping 无参数...");
        return "success";
    }
}

4.springmvc配置

<?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:component-scan base-package="com.wjl"/>
    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven />

</beans>

5.测试

index.jsp 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<h3>入门程序</h3>

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

<a href="user/testRequestMapping">RequestMapping注解无参数</a> <br/>

<a href="user/testRequestMapping?username=heihei">RequestMapping注解</a>
</body>
</html>

success.jsp 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>SUCCESS 成功</h3>
</body>
</html>

四、SpringMVC 请求参数的绑定

1.支持的数据类型

  • 基本类型参数
    包括基本类型和 String 类型

  • POJO 类型参数:
    包括实体类,以及关联的实体类

  • 数组和集合类型参数:
    包括 List 结构和 Map 结构的集合(包括数组)
    SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求。

2.使用要求

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

  • 如果是 POJO 类型,或者它的关联对象:
    要求表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。

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

要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。
给 List 集合中的元素赋值,使用下标。
给 Map 集合中的元素赋值,使用键值对。

第二种:

接收的请求参数是 json 格式数据。需要借助一个注解实现。

注意:
它还可以实现一些数据类型自动转换。内置转换器全都在:

org.springframework.core.convert.support 包下。有:
java.lang.Boolean -> java.lang.String : ObjectToStringConverter
java.lang.Character -> java.lang.Number : CharacterToNumberFactory
java.lang.Character -> java.lang.String : ObjectToStringConverter
java.lang.Enum -> java.lang.String : EnumToStringConverter
java.lang.Number -> java.lang.Character : NumberToCharacterConverter
java.lang.Number -> java.lang.Number : NumberToNumberConverterFactory
java.lang.Number -> java.lang.String : ObjectToStringConverter
java.lang.String -> java.lang.Boolean : StringToBooleanConverter
java.lang.String -> java.lang.Character : StringToCharacterConverter
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory
java.lang.String -> java.lang.Number : StringToNumberConverterFactory
java.lang.String -> java.util.Locale : StringToLocaleConverter
java.lang.String -> java.util.Properties : StringToPropertiesConverter
java.lang.String -> java.util.UUID : StringToUUIDConverter
java.util.Locale -> java.lang.String : ObjectToStringConverter
java.util.Properties -> java.lang.String : PropertiesToStringConverter
java.util.UUID -> java.lang.String : ObjectToStringConverter
......

如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。

3.实例

3.1 POJO 类

Account代码如下:

import com.wjl.User;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public class Account implements Serializable {
    private String username;
    private String password;
    private Double money;
    private List<User> list;
    private Map<String,User> map;
    getter/setter
    public String toString() {}
     
}

User 代码如下:

import java.io.Serializable;
import java.util.Date;
public class User  implements Serializable {
    private String uname;
    private Integer age;
    private Date date;
    setter/getter
    @Override
    public String toString() { }
}

3.2自定义类型转换器

StringToDateConverter 代码如下:

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

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

/**
 * 把字符串转换日期
 */
public class StringToDateConverter implements Converter<String,Date>{
    /**
     * String source    传入进来字符串
     * @param source
     * @return
     */
    public Date convert(String source) {
        // 判断
        if(source == null){
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df =null;
        if(source.contains("-")){
             df = new SimpleDateFormat("yyyy-MM-dd");
        }else{
            df = new SimpleDateFormat("yyyy/MM/dd");
        }
        try {
            // 把字符串转换日期
            return df.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}

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:component-scan base-package="com.wjl"/>
    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.wjl.utils.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven conversion-service="conversionService"/>
</beans>

3.3请求参数乱码问题

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>

  <!--配置解决中文乱码的过滤器-->
  <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>

3.4 控制器

ParamController 代码如下:

package com.wjl.controller;

import com.wjl.User;
import com.wjl.utils.Account;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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

    @RequestMapping(path = "/testParam")
    public String testParam(String username,String password){
        System.out.println("testParam(String username,String password) 执行了...");
        System.out.println("用户名:"+ username);
        System.out.println("密码:"+ password);
        return "success";
    }

    /**
     * 请求参数绑定把数据封装到JavaBean的类中
     * @return
     */
    @RequestMapping("/saveAccount")
    public String saveAccount(Account account){
        System.out.println(" saveAccount 执行...");
        System.out.println(account);
        return "success";
    }

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

    /**
     * 原生的API
     * @return
     */
    @RequestMapping("/testServlet")
    public String testServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行了...");
        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";
    }
}

3.5 测试

param.jsp代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>请求参数的绑定</title>
</head>
<body>
   <%--请求参数绑定--%>
   <a href="param/testParam?username=zhangsan&password=123">请求参数绑定</a> <br/>

   <%--请求参数绑定把数据封装到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>

   <%--请求参数绑定把数据封装到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="text" name="user.uname" /><br/>
       用户年龄:<input type="text" name="user.age" /><br/>
       <input type="submit" value="提交" />
   </form>

   <%--把数据封装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/>

          用户姓名:<input type="text" name="list[0].uname" /><br/>
          用户年龄:<input type="text" name="list[0].age" /><br/>

          用户姓名:<input type="text" name="map['one'].uname" /><br/>
          用户年龄:<input type="text" name="map['one'].age" /><br/>
          <input type="submit" value="提交" />
      </form>
   <%--自定义类型转换器 --%>
      <form action="param/saveUser" method="post">
          用户姓名:<input type="text" name="uname" /><br/>
          用户年龄:<input type="text" name="age" /><br/>
          用户生日:<input type="text" name="date" /><br/>
          <input type="submit" value="提交" />
      </form>
   <br/> <hr/>

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

五、常用注解

5.1 控制器

AnnoController 代码如下:

package com.wjl.controller;

import com.wjl.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

@Controller
@RequestMapping("/anno")
public class AnnoController {

    /**
     * RequestParam
     *   把请求中指定名称的参数给控制器中的形参赋值。
     * 属性:
     *   value:请求参数中的名称。
     *   required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
     * @param username
     * @return
     */
    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(name="name") String username){
        System.out.println("执行了...");
        System.out.println(username);
        return "success";
    }

    /**
     * RequestBody
     * 获取请求体内容。直接使用得到是 key=value&key=value...结构的数据。
     * get 请求方式不适用。
     * 属性:
     * required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值
     * 为 false,get 请求得到是 null。
     * @param body
     * @return
     */
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println("执行了...");
        System.out.println(body);
        return "success";
    }

    /**
     * PathVariable注解
     * 用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
     * url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
     * 属性:
     * value:用于指定 url 中占位符名称。
     * required:是否必须提供占位符。
     * @return
     */
    @RequestMapping(value="/testPathVariable/{sid}")
    public String testPathVariable(@PathVariable(name="sid") String id) {
        System.out.println("执行了...");
        System.out.println(id);
        return "success";
    }

    /**
     * RequestHeader
     * 用于获取请求消息头。
     * 属性:
     * value:提供消息头名称
     * required:是否必须有此消息头
     * 注:
     * 在实际开发中一般不怎么用。
     * @param header
     * @return
     */
    @RequestMapping(value="/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value="Accept") String header, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("执行了...");
        System.out.println(header);
        // return "success";
        // response.sendRedirect(request.getContextPath()+"/anno/testCookieValue");
        return "redirect:/param.jsp";
    }

    /**
     * CookieValue
     * 用于把指定 cookie 名称的值传入控制器方法参数。
     * 属性:
     * value:指定 cookie 的名称。
     * required:是否必须有此 cookie。
     * @return
     */
    @RequestMapping(value="/testCookieValue")
    public String testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){
        System.out.println("执行了...");
        System.out.println(cookieValue);
        return "success";
    }


    /**
     * ModelAttribute注解
     * 该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。
     * 出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可
     * 以修饰有具体返回值的方法。
     * 出现在参数上,获取指定的数据给参数赋值。
     * 属性:
     * value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。
     * 应用场景:
     * 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
     * 例如:
     * 我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数
     * 据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
     * @return
     */
    @RequestMapping(value="/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("abc") User user){
        System.out.println("testModelAttribute执行了...");
        System.out.println(user);
        return "success";
    }
    @ModelAttribute
    public void showUser(String uname, Map<String,User> map){
        System.out.println("showUser执行了...");
        // 通过用户查询数据库(模拟)
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        map.put("abc",user);
    }

    /**
     * SessionAttributes的注解
     * 用于多次执行控制器方法间的参数共享。
     * 属性:
     * value:用于指定存入的属性名称
     * type:用于指定存入的数据类型。
     * @return
     */
    @RequestMapping(value="/testSessionAttributes")
    public String testSessionAttributes(Model model){
        System.out.println("testSessionAttributes...");
        // 底层会存储到request域对象中
        model.addAttribute("msg","美美");
        return "success";
    }

    /**
     * 获取值
     * @param modelMap
     * @return
     */
    @RequestMapping(value="/getSessionAttributes")
    public String getSessionAttributes(ModelMap modelMap){
        System.out.println("getSessionAttributes...");
        String msg = (String) modelMap.get("msg");
        System.out.println(msg);
        return "success";
    }

    /**
     * 清除
     * @param status
     * @return
     */
    @RequestMapping(value="/delSessionAttributes")
    public String delSessionAttributes(SessionStatus status){
        System.out.println("getSessionAttributes...");
        status.setComplete();
        return "success";
    }
    
}

5.2 测试jsp

anno.jsp 代码如下:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <%--常用的注解--%>
    <a href="anno/testRequestParam?name=哈哈">RequestParam</a>
    <br>

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

    <a href="anno/testPathVariable/10">testPathVariable</a>
    <br>

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

    <br>

    <a href="anno/testCookieValue">CookieValue</a>

    <br>

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

    <br>
    <a href="anno/testSessionAttributes">testSessionAttributes</a>
    <a href="anno/getSessionAttributes">getSessionAttributes</a>
    <a href="anno/delSessionAttributes">delSessionAttributes</a>

</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值