Spring MVC 的常用注解

前两天,我的一位好朋友在微信给我留言,说:“让我总结一下Spring MVC常用注解。”我一口答应了,说:“好!”于是我花了两天的时间来整理,今天决定将《Spring MVC的常用注解》分享至我的博客,供大家一起学习探讨。因本人能力有限,如写有不足之处,欢迎大家给我留言指出。

众所周知,Spring是从2.5版本开始引入注解的,常见的注解有:@Controller、@RequestMapping、@RequestParam和@ModleAttribute等类似这样的注解。目前,Spring的版本已经发生了很大的变化,但注解的特性却一直延续下来,并不断扩展,让很多开发者的工作变的更轻松,这都离不开Annotation的强大作用。本文将详细总结Spring MVC常用的8个注解。

本项目源代码下载:Spring MVC常用注解

@Controller注解

@Controller注解是在Spring的org.springframework.stereotype包下,org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,使用@Controller注解的类不需要继承特定的父类或者实现特定的接口,相对之前的版本实现Controller接口变的更加简单。而Controller接口的实现类只能处理一个单一的请求动作,而@Controller注解注解的控制器可以同时支持处理多个请求动作,使程序开发变的更加灵活。

@Controller用户标记一个类,使用它标记的类就是一个Spring MVC Controller对象,即:一个控制器类。Spring使用扫描机制查找应用程序中所有基于注解的控制器类,分发处理器会扫描使用了该注解的方法,并检测该方法是否使用了@RequestMapping注解,而使用@RequestMapping注解的方法才是真正处理请求的处理器。为了保证Spring能找到控制器,我们需要完成两件事:

1、在Spring MVC的配置文件中的头部引入spring-context;

2、使用 <context:component-scan/> 元素,该元素的功能是:启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为Spring的Bean。配置文件如下所示:

<!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean -->
    <context:component-scan base-package="com.qianchunhua.controller"/>

下面将用案例来演示@Controller注解的使用。

今天我将创建一个maven工程,使用pom.xml来导入我们需要的jar包,采用Tomcat 7.0作为maven项目的web服务器。首先在eclipse中new一个maven project,由于我的maven仓库是在本地,我直接将“create a simple project”前面的勾选中。如下图所示:

Spring MVC 的常用注解

点击next。选填信息如下图所示:

Spring MVC 的常用注解

最后,将我们的maven项目导入我们所需要的jar包,jar包都是spring-webmvc所依赖的。具体jar包和创建好的maven项目目录如下图所示:

Spring MVC 的常用注解

在项目的“src/main/java”下创建一个包,包名叫“com.qianchunhua.controller”,在包下创建ControllerTest类,用来演示@Controller注解控制器的使用。如下代码:

package com.qianchunhua.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * ControllerTest是一个基于注解的控制器,
 * 可以同时处理多个请求动作,并且无须实现任何接口。
 * org.springframework.stereotype.Controller注解用于指示该类是一个控制器.
 * @author Cody
 */
@Controller
public class ControllerTest {
    @RequestMapping("/helloWorld")
     public String helloWorld(Model model) {
         model.addAttribute("message", "你好,欢迎访问钱春华的专栏!");
         return "helloWorld";
     }
}

ControllerTest是一个基于@Controller注解的控制器,@RequestMapping注释用来映射一个请求,value=”/helloWorld”表示请求由helloWorld方法进行处理。helloWorld方法接收一个org.springframework.ui.Model类型的参数,本案例在model中添加了一个名为“message”的字符串对象,该对象可以在返回的视图当中通过request对象获取。最后,方法返回一个字符串“helloWorld”作为视图名称。

接下来,我们要创建一个Spring MVC的配置文件,并且从中配置,在我们的maven项目“src/main/webapp/WEB-INF”目录下创建一个springmvc-config.xml,这个xml文件就是我们的Spring MVC配置文件。配置信息如下:

<?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:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
        如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean -->
    <context:component-scan base-package="com.qianchunhua.controller"/>

    <!-- 视图解析器  -->
     <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
        <!-- 前缀 -->
        <property name="prefix">
            <value>/WEB-INF/content/</value>
        </property>
        <!-- 后缀 -->
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>

由于在我们的java文件中使用了注解类型,因此不需要再配置文件中使用xml描述bean。 <context:component-scan base-package="com.qianchunhua.controller"/> 指定需要Spring扫描com.qianchunhua.controller包及其子包下面的所有java文件。最后配置了视图解析器InternalResourceViewResolver来解析视图,将View呈现给用户。视图解析器中配置的prefix属性表示视图的前缀,suffix表示视图的后缀,返回的视图字符串是“helloWorld”,经过视图解析器之后,则视图的完整路径是:/WEB-INF/content/helloWorld.jsp。因此,在这里,我们需要在项目的WEB-INF下,创建一个“content”文件夹,里面用来保存jsp文件,在content文件下创建一个helloWorld.jsp。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@Controller注解</title>
</head>
<body>
    <!-- 页面可以访问Controller传递传递出来的message -->
    ${requestScope.message}
</body>
</html>

需要注意的是,在此配置文件中没有配置处理映射器和处理适配器时,Spring会使用默认的处理映射器和处理适配器处理请求。此外,还需要在web.xml中配置Spring MVC的前端控制器DispatcherServlet。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">
  <display-name>springmvc-comment1</display-name>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</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>

到此,我们就将@Controller注解的案例应用给写完了。下面,我将部署springmvc-comment1项目,在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment1/helloWorld

然后按下回车,看到如下图所示。就表示Spring MVC访问成功!

Spring MVC 的常用注解

@RequestMapping注解

Spring MVC中用于参数绑定的注解有很多,都在org.springframework.web.bind.annotation包中,根据它们处理的request的不同内容可以分为四类(常用的类型)。

第一类:处理request body部分的注解有:@RequestParam和@RequestBody

第二类:处理requet uri部分的注解有:@PathVaribale

第三类:处理request header部分的注解有:@RequestHeader和@CookieValue

第四类:处理attribute类型的注解有:@SessionAttributes和@MoelAttribute

接下来,我将说一说@RequestMapping注解,前面在说@Controller注解的时候已经提到过这个注解是用来处理类和方法发送请求动作,@RequestMapping注解也在org.springframework.web.bind.annotation包中,但是严格来说,它并不属于参数绑定的注解。因此,@RequestMapping可以用来注释一个控制器类,在这种情况下,所有的方法都将映射为相对于类级别的请求,表示该控制器处理的所有请求都被映射到value属性所指示的路径下。如下示例伪代码:

@Controller
@RequestMapping(value="/user")
public class UserController {
    @RequestMapping(value="/register")
     public String register() {
         return "register";
     }
     @RequestMapping(value="/login")
     public String login() {
         return "login";
     }

如上代码,由于UserController类中加了value=”/user”的@RequestMapping注解,因此所有相关路径都要加上”/user”,此时方法被映射到如下请求ur地址:

http://localhost:8088/user/register

http://localhost:8088/user/login

那么使用@RequestMapping注解有哪些属性呢?其实它有8种属性,在此我就不一一介绍着8个属性了,我们在开发中常用到的就只有6种,还有2个如感兴趣的可以自行百度。下面我将6种属性逐一介绍。

1、value属性

@RequestMapping是用来映射一个请求和一种方法。可以使用@RequestMapping注释一个方法或者类。

一个采用@RequestMapping注解的方法将成为一个请求的处理方法。如下伪代码:

@RequestMapping(value="/hello")
public ModelAndView hello() {
    return...;
}

该伪代码中使用@RequestMapping注释value属性将URL映射到方法上。在这个例子中,将hello映射到hello方法上,使用如下url访问应用时将由hello方法进行处理: http://localhost:8088/context/hello

由于value属性是@RequestMapping注释的默认属性,因此,如果只有唯一的属性,则可以省略属性名,即如下两个标注含义相同。

@RequestMapping(value="/hello")
@RequestMapping("/hello")

但如果有超过一个属性,就必须写上value属性名称。value属性的值也可以是一个空字符串,此时方法被映射到如下url请求:

http://localhost:8088/context

2、method属性

该属性用来指示该方法仅仅处理哪些HTTP请求方式。如下伪代码:

@RequestMapping(value="/hello",method=RequestMethod.POST)

以上代码method=RequestMethod.POST表示该方法只支持POST请求,也可以同时支持多个HTTP请求。如下:

@RequestMapping(value="/hello",method={RequestMethod.POST,method=RequestMethod.GET})

若没有指定method属性值,则请求处理方法可以任意的请求HTTP方式。

3、consumes属性

该属性指定处理请求的提交内容类型(Content-Type)。如下伪代码:

@RequestMapping(value="/hello",method=RequestMethod.POST,consumes="application/json")

表示方法仅处理request Content-Type为”application/json”类型的请求。

4、produces属性

该属性指定返回的内容类型,返回的内容类型必须是request请求头(Accept)中所包含的类型。如下伪代码:

@RequestMapping(value="/hello",method=RequestMethod.POST,produces="application/json")

方法仅处理request请求中Accept头中包含了”application/json”的请求,同时知名了返回的内容类型为application/json。

5、params属性

该属性指定request中必须包含某些参数值时,才让该方法处理。如下伪代码:

@RequestMapping(value="/hello",method=RequestMethod.POST,params="myParam=myValue")

方法仅处理其中名为“myPara”,值为“myValue”的请求。

6、headers属性

该属性指定request中必须包含某些特性的header值,才能让该方法处理请求。如下伪代码:

@RequestMapping(value="/hello",method=RequestMethod.POST,headers="Referer=http://www.qianchunhua.com/")

方法仅处理request的header中包含了指定的“Referer”请求头和对应值为“ http://www.qianchunhua.com ”的请求。

@RequestParam注解

下面来说org.springframework.web.bind.annotation包下的第三个注解,即:@RequestParam注解,该注解类型用于将指定的请求参数赋值给方法中的形参。那么@RequestParam注解有什么属性呢?它有4种属性,下面将逐一介绍这四种属性:

1、name属性

该属性的类型是String类型,它可以指定请求头绑定的名称;

2、value属性

该属性的类型是String类型,它可以设置是name属性的别名;

3、required属性

该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;

4、defalutValue属性

该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。

请求处理方法参数的可选类型位Java的8种基本数据类型和String。如下示例伪代码:

@RequestMapping(value="/hello")
public ModelAndView hello(
    @RequestParam("loginname") String loginname,
    @RequestParam("password") String password) {
    return...;
}

假设请求如下: http://localhost:8088/springmvc-comment1/login?loginname=qianch&password=123456

以上代码会将请求中的loginname参数的值“qianch”赋给loginname变量,password参数的值“123456”赋给password变量。

下面将通过案例演示@RequestMapping和@RequestParam注解的应用。

还在刚才我创建的springmvc-comment1项目中进行演示,首先,还在项目的“src/main/java”下创建一个包,包名叫“com.qianchunhua.domain”,在包下创建User类,该类是一个域对象,主要用于封装前台页面传来的数据。如下代码:

package com.qianchunhua.domain;

import java.io.Serializable;
// 域对象,实现序列化接口
public class User implements Serializable{

    // 私有字段
    private String loginname;
    private String password;
    private String username;

    // 公共构造器
    public User() {
        super();
    }

    // set/get方法
    public String getLoginname() {
        return loginname;
    }
    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

}

在刚才创建的“com.qianchunhua.controller”包下再创建一个UserController类,该类主要模拟用户的注册。代码如下:

package com.qianchunhua.controller;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.qianchunhua.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
// RequestMapping可以用来注释一个控制器类,此时,所有方法都将映射为相对于类级别的请求, 
// 表示该控制器处理所有的请求都被映射到 value属性所指示的路径下
@RequestMapping(value="/user")
public class UserController {   
    // 静态List<User>集合,此处代替数据库用来保存注册的用户信息
    private static List<User> userList; 
    // UserController类的构造器,初始化List<User>集合
    public UserController() {
        super();
        userList = new ArrayList<User>();
    }
    // 静态的日志类LogFactory
    private static final Log logger = LogFactory
            .getLog(UserController.class);

    // 该方法映射的请求为http://localhost:8088/springmvc-comment1/user/register,该方法支持GET请求
    @RequestMapping(value="/register",method=RequestMethod.GET)
     public String registerForm() {
         logger.info("register GET方法被调用...");
         // 跳转到注册页面
         return "registerForm";
     }

    // 该方法映射的请求为http://localhost:8088/springmvc-comment1/user/register,该方法支持POST请求
     @RequestMapping(value="/register",method=RequestMethod.POST)
     // 将请求中的loginname参数的值赋给loginname变量,password和username同样处理
     public String register(
             @RequestParam("loginname") String loginname,
             @RequestParam("password") String password,
             @RequestParam("username") String username) {
         logger.info("register POST方法被调用...");
         // 创建User对象
         User user = new User();
         user.setLoginname(loginname);
         user.setPassword(password);
         user.setUsername(username);
         // 模拟数据库存储User信息
         userList.add(user);
         // 跳转到登录页面
         return "loginForm";
     }

    // 该方法映射的请求为http://localhost:8088/springmvc-comment1/user/login
     @RequestMapping("/login")
     public String login(
            // 将请求中的loginname参数的值赋给loginname变量,password同样处理
             @RequestParam("loginname") String loginname,
             @RequestParam("password") String password,
             Model model) {
         logger.info("登录名:"+loginname + " 密码:" + password);
         // 到集合中查找用户是否存在,此处用来模拟数据库验证
         for(User user : userList){
             if(user.getLoginname().equals(loginname) && user.getPassword().equals(password)) {
                 model.addAttribute("user",user);
                 return "welcome";
             }
         }
         return "loginForm";
     }

}

UserController类的代码解释如下:

(1)UserController类使用了@Controller注解,是一个控制器类;

(2)UserController类上面使用了@RequestMapping(value=”/user”)注解,表示该控制器处理的所有请求都被映射到user路径下;

(3)本来没有使用数据库存储用户注册信息,所以定义了一个静态的List集合userList来代替数据库存储用户数据;

(4)registerForm方法使用了@RequestMapping(value=”/register”,method=RequestMethod.GET)注解,表示该方法映射的请求为 http://localhost:8088/springmvc-comment1/user/register ,并且只支持GET请求。该方法返回字符串“registerForm”,参考springmvc-config.xml中的配置信息,可以知道该方法只是跳转到registerForm.jsp注册页面;

(5)register方法使用了@RequestMapping(value=”/register”,method=RequestMethod.POST)注解,表示该方法映射的请求为 http://localhost:8088/springmvc-comment1/user/register ,并且只支持POST请求。该方法使用@RequestParam注解将指定的请求参数赋值给方法中的形参,之后创建了一个User对象保存用户传递的注册信息,最后将User对象存储到userList集合当中,之后的登录页面就可以到userList集合当中进行用户登录业务逻辑判断。该方法返回字符串“loginForm”,并跳转到loginForm.jsp登录页面;

(6)login方法使用了@RequestMapping(“/login”)注解,表示该方法映射的请求为 http://localhost:8088/springmvc-comment1/user/login ,这里没有设置method属性表示支持所有方式的请求。该方法也使用@RequestParam注解将指定的请求赋值给方法中的形参。之后到集合中查找用户是否存在,此处用来模拟数据库验证。login方法中海油一个参数Model对象,调用该对象的addAttribute方法可以将数据添加到request当中。最后,如果用户登录成功则返回字符串“loginForm”,并跳转到loginForm.jsp页面。

我们需要在项目的content文件夹下,创建一个registerForm.jsp。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册页面</title>
</head>
<body>
<h3>注册页面</h3>
<form action="register" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
            <td><label>真实姓名: </label></td>
             <td><input type="text" id="username" name="username" ></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="注册"></td>
         </tr>
     </table>
</form>
</body>
</html>

registerForm.jsp是一个注册页面,用户可以输入登录名、密码和真实姓名,该表单被提交到register请求。注意,这里使用的是POST方式,响应请求是UserController类的register方法。

在项目的content文件夹下,创建一个loginForm.jsp。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="login" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

loginForm.jsp是一个登录页面,用户可以输入登录名和密码,该表单被提交到login请求。这里使用的是POST方式,响应请求的是UserController类的login方法。

在项目的content文件夹下,创建一个welcome.jsp。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@RequestMapping注解</title>
</head>
<body>
<!-- 页面可以访问Controller传递传递出来的模型User对象 -->
欢迎[${requestScope.user.username }]登陆成功!
<br>
</body>
</html>

welcome.jsp是一个欢迎页面,用户登录成功后跳转到该页面,该页面使用了EL表达式访问request当中的user对象的username属性。此外,我们还需要配置web.xml和Spring MVC的一些相关信息,和之前演示@Controller注解的方式一样,因为每次都基本一致,故此处不再说了,请自行可以配置,可参考本案例附加的源码

最后我将部署springmvc-comment1项目,在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment1/user/register

如下图,就表示Spring MVC成功跳转到注册页面registerForm.jsp。

Spring MVC 的常用注解

输入用户名:qianch,密码:123456,真实姓名:钱春华,点击注册按钮。请求将会被提交到UserController类的register方法进行注册。注册的用户信息会保存到UserController类的userList静态集合中。注册成功,将会跳转如下图登录页面。

Spring MVC 的常用注解

输入用户名:qianch,密码:123456,点击登录按钮。请求将会被提交到UserController类的rlogin方法进行验证登录,验证成功,将会跳转如下图欢迎页面。

Spring MVC 的常用注解

@PathVaribale注解

下面来说org.springframework.web.bind.annotation包下的第四个注解,即:@PathVaribale注解,该注解类型可以非常方便的获得请求url中的动态参数。@PathVaribale注解只支持一个属性value,类型String,表示绑定的名称,如果省略则默认绑定同名参数。如下示例伪代码:

@RequestMapping(value="/pathVariableTest/{userId})
public void pathVariableTest(@PathVaribale Integer userId)

假如请求的url地址为: http://localhost:8088/springmvc-comment1/pathVariableTest/1 ,则自动将url中模板变量{userId}绑定到通过@PathVaribale注解的同名参数上,即userId变量将被赋值为1。

@RequestHeader注解

下面来说org.springframework.web.bind.annotation包下的第五个注解,即:@RequestHeader注解,该注解类型用于将请求的头的信息区域数据映射到功能处理方法的参数上。

那么@RequestHeader注解有什么属性呢?它和@RequestParam注解一样,也有4种属性,分别如下:

1、name属性

该属性的类型是String类型,它可以指定请求头绑定的名称;

2、value属性

该属性的类型是String类型,它可以设置是name属性的别名;

3、required属性

该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;

4、defalutValue属性

该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。

如下示例伪代码:

@RequestMapping(value="/requestHeaderTest")
public void requestHeaderTest(
    @RequestHeader("User-Agent") String userAgent,
    @RequestHeader(value="Accept") String[] accepts) {
}

以上配置自动将请求头“User-Agent”的值赋到userAgent变量上,并将“Accept”请求头的值赋到accept参数上。

@CookieValue注解

下面来说org.springframework.web.bind.annotation包下的第六个注解,即:@CookieValue注解,该注解类型用于将请求的Cookie数据映射到功能处理方法的参数上。

同样,它和@RequestHeader,还有@RequestParam注解一样,有相同的4种属性,分别如下:

1、name属性

该属性的类型是String类型,它可以指定请求头绑定的名称;

2、value属性

该属性的类型是String类型,它可以设置是name属性的别名;

3、required属性

该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;

4、defalutValue属性

该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。

如下示例伪代码:

@RequestMapping(value="/cookieValueTest")
public void cookieValueTest(
    @CookieValue(value="JSESSIONID",defaultValue="") String sessionId) {
}

以上配置会自动将JSESSIONID值设置到sessionId参数上,defaultValu表示Cookie中没有JSESSIONID时默认为空。

@SessionAttributes注解

下面来说org.springframework.web.bind.annotation包下的第七个注解,即:@SessionAttributes注解,该注解类型允许我们有选择地指定Model中的哪些属性需要转存到HttpSession对象当中。

@SessionAttributes注解有三个属性,分别如下:

1、names属性

该属性的类型是String[],它可以指定Model中属性的名称,即存储在HttpSession当中的属性名称;

2、value属性

该属性的类型是String[],它可以设置names属性的别名;

3、types属性

该属性的类型是 Class<?>[] ,它可以指定参数是否必须绑定。

注意:@SessionAttributes只能声明在类似,而不能声明在方法上。

下面将通过案例来演示@SessionAttributes注解的使用。

在刚才创建的“com.qianchunhua.controller”包下再创建一个SessionAttributesController类。代码如下:

package com.qianchunhua.controller;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.qianchunhua.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;


// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
// 将Model中的属性名为user的放入HttpSession对象当中
@SessionAttributes("user")
public class SessionAttributesController {
    // 静态的日志类LogFactory
    private static final Log logger = LogFactory.getLog(SessionAttributesController.class); 
    // 该方法映射的请求为http://localhost:8088/springmvc-comment1/{formName}
    @RequestMapping(value="/{formName}")
     public String loginForm(@PathVariable String formName){
        // 动态跳转页面
        return formName;
    }

    // 该方法映射的请求为http://localhost:8088/springmvc-comment1/login
    @RequestMapping(value="/login")
     public String login(
             @RequestParam("loginname") String loginname,
             @RequestParam("password") String password,
             Model model ) {
         // 创建User对象,装载用户信息
         User user = new User();
         user.setLoginname(loginname);
         user.setPassword(password);
         user.setUsername("admin");
         // 将user对象添加到Model当中
         model.addAttribute("user",user);
         return "welcome";
     }
}

接下来在“content”文件夹下创建loginForm.jsp和registerForm.jsp,和之前的代码一样。代码如下:

loginForm.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="login" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

registerForm.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册页面</title>
</head>
<body>
<h3>注册页面</h3>
<form action="register" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
            <td><label>真实姓名: </label></td>
             <td><input type="text" id="username" name="username" ></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="注册"></td>
         </tr>
     </table>
</form>
</body>
</html>

最后我将部署springmvc-comment1项目,在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment1/loginForm

会看到如下图测试@SessionAttributes注解的登录页面。

Spring MVC 的常用注解

输入登录名:qianch,密码:123456,点击登录按钮。请求将会被提交到SessionAttributesController类的login方法,该方法会创建User对象来保护数据,并将其设置到Model当中。因为类上面使用了@SessionAttributes注解,所以User同时也会被设置到HttpSession作用域当中。方法执行完成之后跳转如下图欢迎页面。

Spring MVC 的常用注解

这里可以看到,User对象呗成功设置到了HttpSession作用域当中。

注意:@SessionAttributes还有如下写法:

@SessionAttributes(types={User.class},value="user")

还可以设置多个对象到HttpSession当中:

@SessionAttributes(types={User.class,Dept.calss},value="user","dept")

types属性用来指定放入HttpSession当中的对象类型。

@ModelAttribute注解

接下来要说org.springframework.web.bind.annotation包下的第八个注解,也就是今天要说的Spring MVC常用注解的最后一个,即:@ModelAttribute注解,该注解类型将请求参数绑定到Model对象。@ModelAttribute注解只支持一个属性value,类型为String,表示绑定的属性名称。

@ModelAttribute注解是使用方式有很多种,下面将通过@ModelAttribute注解的5种方式来演示@ModelAttribute注解应用。

因这个注解用到的方式很多,因此我在我的eclipse中重新再创建一个新的maven工程,名叫“springmvc-comment2”,和创建一个maven工程一样,我们需要让pom.xml导入所需要的jar包。具体jar包和创建好的maven项目目录如下图所示:

Spring MVC 的常用注解

在项目的“src/main/java”下创建两个包,包名叫“com.qianchunhua.controller和com.qianchunhua.domain”,在controller包下创建FormController类。如下代码:

package com.qianchunhua.controller;

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


// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class FormController {
    // 该方法映射的请求为http://localhost:8080/ModelAttributeTest/{formName}
    @RequestMapping(value="/{formName}")
     public String loginForm(@PathVariable String formName){
        // 动态跳转页面
        return formName;
    }

}

在domain包下创建User类。如下代码:

package com.qianchunhua.domain;

import java.io.Serializable;
// 域对象,实现序列化接口
public class User implements Serializable{

    // 私有字段
    private String loginname;
    private String password;
    private String username;

    // 公共构造器
    public User() {
        super();
    }

    public User(String loginname, String password, String username) {
        super();
        this.loginname = loginname;
        this.password = password;
        this.username = username;
    }

    // set/get方法
    public String getLoginname() {
        return loginname;
    }
    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

}

在项目的webapp下面创建一个index.jsp页面,用来测试@ModelAttribute注解访问不同页面的首页,通过超链接的方式查看测试@ModelAttribute注解不同的使用方式。代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute的不同用法</h3>
<a href="loginForm1">测试@ModelAttribute(value="")注释返回具体类的方法 </a><br><br>
<a href="loginForm2">测试@ModelAttribute注释void返回值的方法</a><br><br>
<a href="loginForm3">测试@ModelAttribute注释返回具体类的方法</a><br><br>
<a href="loginForm4">测试@ModelAttribute和@RequestMapping同时注释一个方法 </a><br><br>
<a href="loginForm5">测试@ModelAttribute注释一个方法的参数 </a><br><br>
</body>
</html>

下面,将开始逐一介绍@ModelAttribute注解的五种使用方式。

1、测试@ModelAttribute(value=”“)注释返回具体类的方法

我们在WEB-INF下的content文件夹下创建loginForm1.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute(value="")注释返回具体类的方法</h3>
<form action="login1" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

在controller包下创建ModelAttribute1Controller类。如下代码:

package com.qianchunhua.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class ModelAttribute1Controller {
    // 使用@ModelAttribute注释的value属性,来指定model属性的名称,model属性对象就是方法的返回值
    @ModelAttribute("loginname")
    public String userModel1( 
        @RequestParam("loginname") String loginname){
        return loginname;
    }
    @RequestMapping(value="/login1")
     public String login1() {
         return "result1";
     }

}

ModelAttribute1Controller类除了@RequestMapping映射的login1方法之外,还提供了一个userModel1方法,该方法上有一个@ModelAttribute注解默认的value值为“loginname”,用来指定model属性的名称,而model属性的值就是userModel1方法的返回值。被@ModelAttribute注解的userModel1方法会先于login1调用,它把请求参数loginname的值赋给loginname变量,并设置了一个属性loginname到Model当中,而属性的值就是loginname变量的值。

下面在content文件夹下创建result1.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute(value="")注释返回具体类的方法</title>
</head>
<body>
访问request作用范围域中的loginname对象:${requestScope.loginname }<br>
<br>
</body>
</html>

在跳转的result1.jsp中可以访问到由@ModelAttribute设置的loginname的值。我们需要在项目中配置web.xml和springmvc-config.xml。配置信息如下:

springmvc-config.xml:
<!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
        如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean -->
    <context:component-scan base-package="com.qianchunhua.controller"/>

    <!-- 视图解析器  -->
     <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
        <!-- 前缀 -->
        <property name="prefix">
            <value>/WEB-INF/content/</value>
        </property>
        <!-- 后缀 -->
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

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">
  <display-name>springmvc-comment2</display-name>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</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>

下面,我将部署springmvc-comment2项目,在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment2/index.jsp

然后按下回车,看到如下图所示。就表示Spring MVC成功跳转初始页面index.jsp。

Spring MVC 的常用注解

点击“测试@ModelAttribute(value=”“)注释返回具体类的方法”超链接发送请求,跳转到loginForm1.jsp。如下图所示:

Spring MVC 的常用注解

输入登录名:qianch,点击登录按钮发送请求,先将调用userModel1方法,在调用login1方法,并跳转到result1.jsp页面。如下图所示:

Spring MVC 的常用注解

可以看到,在request作用域中访问到了Model的值。

2、测试@ModelAttribute注释void返回值的方法

我们在WEB-INF下的content文件夹下创建loginForm2.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute注释void返回值的方法</h3>
<form action="login2" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

在controller包下创建ModelAttribute2Controller类。如下代码:

package com.qianchunhua.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class ModelAttribute2Controller{
    // model属性名称和model属性对象由model.addAttribute()实现,前提是要在方法中加入一个Model类型的参数。
    // 注意:当URL或者post中不包含对应的参数时,程序会抛出异常。
    @ModelAttribute
    public void userModel2( 
            @RequestParam("loginname") String loginname,
            @RequestParam("password") String password,
             Model model){
        model.addAttribute("loginname", loginname);
        model.addAttribute("password", password);
    }

    @RequestMapping(value="/login2")
     public String login2() {
         return "result2";
     }

}

ModelAttribute2Controller类除了@RequestMapping映射的login2方法之外,还提供了一个userModel2方法,该方法上有一个@ModelAttribute注解。userModel2方法会先于login2调用,它把请求参数值赋给对应变量,model属性名称和值由model.addAttribute()方法实现,提前是要在方法中加入一个Model类型的参数。

下面在content文件夹下创建result2.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute注释void返回值的方法</title>
</head>
<body>
访问request作用范围域中的loginname对象:${requestScope.loginname }<br>
访问request作用范围域中的password对象:${requestScope.password }<br>
<br>
</body>
</html>

在跳转的result2.jsp中可以访问到由@ModelAttribute设置的loginname和password的值。在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment2/index.jsp

然后按下回车,看到如下图所示。就表示Spring MVC成功跳转初始页面index.jsp。

Spring MVC 的常用注解

点击“测试@ModelAttribute注释void返回值的方法”超链接发送请求,跳转到loginForm2.jsp。如下图所示:

Spring MVC 的常用注解

输入登录名:qianch,密码:123456,点击登录按钮发送请求,先将调用userMode2方法,在调用login2方法,并跳转到result2.jsp页面。如下图所示:

Spring MVC 的常用注解

可以看到,在request作用域中访问到了Model的值。

3、测试@ModelAttribute注释返回具体类的方法

我们在WEB-INF下的content文件夹下创建loginForm3.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute注释返回具体类的方法</h3>
<form action="login3" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

在controller包下创建ModelAttribute3Controller类。如下代码:

package com.qianchunhua.controller;

import java.util.ArrayList;
import java.util.List;
import com.qianchunhua.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class ModelAttribute3Controller {    
    // 静态List<User>集合,此处代替数据库用来保存注册的用户信息
    private static List<User> userList; 
    // UserController类的构造器,初始化List<User>集合
    public ModelAttribute3Controller() {
        super();
        userList = new ArrayList<User>();
        User user1 = new User("qianch","123456","测试用户");
        User user2 = new User("admin","123456","管理员");
        // 存储User用户,用于模拟数据库数据
        userList.add(user1);
        userList.add(user2);
    }

    // 根据登录名和密码查询用户,用户存在返回包含用户信息的User对象,不存在返回null
    public User find(String loginname,String password){
        for(User user: userList){
            if(user.getLoginname().equals(loginname) && user.getPassword().equals(password)){
                return user;
            }
        }
        return null;
    }

    // model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称是user。
    // 这个例子中model属性名称由返回对象类型隐含表示,model属性对象就是方法的返回值。它不需要指定特定的参数。
    @ModelAttribute
    public User userModel3( 
            @RequestParam("loginname") String loginname,
            @RequestParam("password") String password){
        return find(loginname, password);
    }

    @RequestMapping(value="/login3")
    public String login3() {
         return "result3";
    }

}

ModelAttribute3Controller类除了@RequestMapping映射的login3方法之外,还提供了一个userModel3方法,该方法上有一个@ModelAttribute注解。userModel3方法会先于login3调用,这里model属性的名称没有被指定,它由@ModelAttribute注解的userModel3方法的返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称就是user。此处find(loginname,password)方法是用来模拟数据库根据用户名和密码查询用户功能实现。

下面在content文件夹下创建result3.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute注释返回具体类的方法</title>
</head>
<body>
访问request作用范围域中的user对象:${requestScope.user.username }<br>
<br>
</body>
</html>

在跳转的result3.jsp中可以访问到由@ModelAttribute设置的loginname和password的值。在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment2/index.jsp

然后按下回车,看到如下图所示。就表示Spring MVC成功跳转初始页面index.jsp。

Spring MVC 的常用注解

点击“测试@ModelAttribute注释返回具体类的方法”超链接发送请求,跳转到loginForm3.jsp。如下图所示:

Spring MVC 的常用注解

输入登录名:qianch,密码:123456,点击登录按钮发送请求,先将调用userMode3方法,在调用login3方法,并跳转到result3.jsp页面。如下图所示:

Spring MVC 的常用注解

可以看到,在request作用域中访问到了User对象。

4、测试@ModelAttribute和@RequestMapping同时注释一个方法

我们在WEB-INF下的content文件夹下创建loginForm4.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute和@RequestMapping同时注释一个方法</h3>
<form action="login4" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

在controller包下创建ModelAttribute4Controller类。如下代码:

package com.qianchunhua.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class ModelAttribute4Controller{

     // 这时这个方法的返回值并不是表示一个视图名称,而是model属性的值,视图名称是@RequestMapping的value值。
     // Model属性名称由@ModelAttribute(value=””)指定,相当于在request中封装了username(key)=admin(value)。
    @RequestMapping(value="/login4")
    @ModelAttribute(value="username")
     public String login4() {
         return "admin";
     }

}

ModelAttribute4Controller中,@RequestMapping和@ModelAttribute同时注释一个方法,此时login4方法的返回值并不是一个视图的名称,而是model属性的值,视图名称是@RequestMapping的value值“/login4”。Model的属性名称由@ModelAttribute的value指定,这相当于在request中封装了username(key)=admin(value)。

下面在content文件夹下创建login4.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute和@RequestMapping同时注释一个方法</title>
</head>
<body>
访问request作用范围域中的username对象:${requestScope.username }<br>
<br>
</body>
</html>

在浏览器中输入如下url地址来测试应用:

http://localhost:8088/springmvc-comment2/index.jsp

然后按下回车,看到如下图所示。就表示Spring MVC成功跳转初始页面index.jsp。

Spring MVC 的常用注解

点击“测试@ModelAttribute和@RequestMapping同时注释一个方法”超链接发送请求,跳转到loginForm4.jsp。如下图所示:

Spring MVC 的常用注解

输入登录名:qianch,密码:123456,点击登录按钮发送请求,先调用login4方法,跳转到login4.jsp页面。如下图所示:

Spring MVC 的常用注解

可以看到,在request作用域中访问到了Uusername的值,也就是login4方法返回值“admin”。

5、测试@ModelAttribute注释一个方法的参数

我们在WEB-INF下的content文件夹下创建loginForm5.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute</title>
</head>
<body>
<h3>测试@ModelAttribute注释一个方法的参数 </h3>
<form action="login5" method="post">
     <table>
         <tr>
            <td><label>登录名: </label></td>
             <td><input type="text" id="loginname" name="loginname" ></td>
         </tr>
         <tr>
            <td><label>密码: </label></td>
             <td><input type="password" id="password" name="password"></td>
         </tr>
         <tr>
             <td><input id="submit" type="submit" value="登录"></td>
         </tr>
     </table>
</form>
</body>
</html>

在controller包下创建ModelAttribute5Controller类。如下代码:

package com.qianchunhua.controller;

import com.qianchunhua.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
// Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作
@Controller
public class ModelAttribute5Controller {
        // model属性名称就是value值即”user”,model属性对象就是方法的返回值
        @ModelAttribute("user")
        public User userModel5( 
                @RequestParam("loginname") String loginname,
                @RequestParam("password") String password){
            User user = new User();
            user.setLoginname(loginname);
            user.setPassword(password);
            return user;
        }

        // @ModelAttribute("user") User user注释方法参数,参数user的值来源于userModel5()方法中的model属性。
        @RequestMapping(value="/login5")
         public String login5(@ModelAttribute("user") User user) {
            user.setUsername("管理员");
            return "result5";
         }
}

ModelAttribute5Controller类除了@RequestMapping映射的login5方法之外,还提供了一个userModel5方法,该方法上有一个@ModelAttribute(“user”)注解。userModel5方法会先于login5调用,这里model属性的名称就是vaule值,即“user”,model属性对象就是userModel5方法的返回值User。

login5方法的参数User使用了@ModelAttribute(“user”)注解,表示参数user的值就是userModel5()方法中的model属性。

下面在content文件夹下创建result5.jsp文件。如下代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试@ModelAttribute注释一个方法的参数</title>
</head>
<body>
访问request作用范围域中的user对象:${requestScope.user.username }<br>
<br>
</body>
</html>

在浏览器中输入如下url地址来测试应用: http://localhost:8088/springmvc-comment2/index.jsp

然后按下回车,看到如下图所示。就表示Spring MVC成功跳转初始页面index.jsp。

Spring MVC 的常用注解

点击“测试@ModelAttribute注释一个方法的参数 ”超链接发送请求,跳转到loginForm5.jsp。如下图所示:

Spring MVC 的常用注解

输入登录名:qianch,密码:123456,点击登录按钮发送请求,而后将调用login5方法,并跳转到result5.jsp页面。如下图所示:

Spring MVC 的常用注解

可以看到,在request作用域中访问到了User对象。

小结:@ModelAttribute注解常用的5种使用方法,而且用法都非常灵活,因此我们开发者可以根据业务的需求来选择使用。以上就是这两天总结的Spring MVC常用的8个注解以及它们的应用,欢迎朋友们留言一起交流,谢谢!

原文 

http://blog.csdn.net/qian_ch/article/details/73826663

PS:如果您想和业内技术大牛交流的话,请加qq群(527933790)或者关注微信公众 号(AskHarries),谢谢!

转载请注明原文出处:Harries Blog™ » Spring MVC 的常用注解

赞 (0)

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址