Spring基础知识(13)- Spring MVC (三) | Controller 传递请求参数、访问静态资源
1. Controller 传递请求参数
Spring MVC Controller 传递请求参数有多种方式,下面介绍这些方式,可以根据实际情况选择合适的接收方式。
1) 通过处理方法的形参接收请求参数
通过处理方法的形参接收请求参数就是直接把表单参数写在控制器类相应方法的形参中,即形参名称与请求参数名称完全相同。该接收参数方式适用于 get 和 post 提交请求方式。示例代码如下:
1 @RequestMapping(value="/login/post", method=RequestMethod.POST) 2 public String loginPost(String username, String password, Model model) { 3 if ("admin".equals(username) && "123456".equals(password)) { 4 model.addAttribute("message", "success - 通过处理方法的形参接收请求参数"); 5 return "success"; 6 } else { 7 model.addAttribute("message", "failed - 通过处理方法的形参接收请求参数"); 8 return "failed"; 9 } 10 }
2) 通过 HttpServletRequest 接收请求参数
通过 HttpServletRequest 接收请求参数适用于 get 和 post 提交请求方式,示例代码如下:
1 @RequestMapping("/login/post2") 2 public String loginPost2(HttpServletRequest request, Model model) { 3 String username = request.getParameter("username"); 4 String password = request.getParameter("password"); 5 6 if ("admin".equals(username) && "123456".equals(password)) { 7 model.addAttribute("message", "success - 通过 HttpServletRequest 接收请求参数"); 8 return "success"; 9 } else { 10 model.addAttribute("message", "failed - 通过 HttpServletRequest 接收请求参数"); 11 return "failed"; 12 } 13 }
3) 通过 @PathVariable 接收 URL 中的请求参数
通过 @PathVariable 获取 URL 中的参数,示例代码如下。
1 @RequestMapping("/login/post3/{username}/{password}") 2 public String loginPost3(@PathVariable String username, @PathVariable String password, Model model) { 3 4 if ("admin".equals(username) && "123456".equals(password)) { 5 model.addAttribute("message", "success - 通过 @PathVariable 接收 URL 中的请求参数"); 6 return "success"; 7 } else { 8 model.addAttribute("message", "failed - 通过 @PathVariable 接收 URL 中的请求参数"); 9 return "failed"; 10 } 11 }
在访问 “http://localhost:9090/index/login/admin/123456” 路径时,上述代码会自动将 URL 中的模板变量 {username} 和 {password} 绑定到通过 @PathVariable 注解的同名参数上,即 username=admin,password=123456。
4) 通过 @RequestParam 接收请求参数
在方法入参处使用 @RequestParam 注解指定其对应的请求参数。@RequestParam 有以下三个参数:
value:参数名
required:是否必须,默认为 true,表示请求中必须包含对应的参数名,若不存在将抛出异常
defaultValue:参数默认值
通过 @RequestParam 接收请求参数适用于 get 和 post 提交请求方式,示例代码如下。
1 @RequestMapping("/login/post4") 2 public String loginPost4(@RequestParam String username, @RequestParam String password, Model model) { 3 4 if ("admin".equals(username) && "123456".equals(password)) { 5 model.addAttribute("message", "success - 通过 @RequestParam 接收请求参数"); 6 return "success"; 7 } else { 8 model.addAttribute("message", "failed - 通过 @RequestParam 接收请求参数"); 9 return "failed"; 10 } 11 }
该方式与 “通过处理方法的形参接收请求参数” 部分的区别如下:当请求参数与接收参数名不一致时,“通过处理方法的形参接收请求参数” 不会报 404 错误,而 “通过 @RequestParam 接收请求参数” 会报 404 错误。
5) 通过实体 Bean 接收请求参数
实体 Bean 接收请求参数适用于 get 和 post 提交请求方式。需要注意,Bean 的属性名称必须与请求参数名称相同。示例代码如下。
1 @RequestMapping("/login/post5") 2 public String loginPost5(User user, Model model) { 3 4 if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) { 5 model.addAttribute("message", "success - 通过实体 Bean 接收请求参数"); 6 return "success"; 7 } else { 8 model.addAttribute("message", "failed - 通过实体 Bean 接收请求参数"); 9 return "failed"; 10 } 11 12 }
6) 通过 @ModelAttribute 接收请求参数
@ModelAttribute 注解用于将多个请求参数封装到一个实体对象中,从而简化数据绑定流程,而且自动暴露为模型数据,在视图页面展示时使用。
而 “通过实体 Bean 接收请求参数” 中只是将多个请求参数封装到一个实体对象,并不能暴露为模型数据(需要使用 model.addAttribute 语句才能暴露为模型数据,后面在数据绑定与模型数据中会讲解)。
通过 @ModelAttribute 注解接收请求参数适用于 get 和 post 提交请求方式,示例代码如下。
1 @RequestMapping("/login/post6") 2 public String loginPost6(@ModelAttribute("user") User user, Model model) { 3 4 if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) { 5 model.addAttribute("message", "success - 通过 @ModelAttribute 接收请求参数"); 6 return "success"; 7 } else { 8 model.addAttribute("message", "failed - 通过 @ModelAttribute 接收请求参数"); 9 return "failed"; 10 } 11 12 }
2. 访问静态资源
静态资源指应用内的资源文件,如 *.html、*.js、*.css 、*.jpg 等静态文件,这些文件放在 webapp 目录下或其子目录下。
Spring MVC 默认不能加载这些静态资源,这里介绍两种方式配置加载静态资源。
1) 配置 web.xml
Spring MVC 本质上相当于 Servlet,可以使用 DefaultServlet 来处理静态资源,DefaultServlet 在 tomat 的安装目录下的 conf/web.xml 中的定义,如下:
1 <servlet> 2 <servlet-name>default</servlet-name> 3 <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> 4 <init-param> 5 <param-name>debug</param-name> 6 <param-value>0</param-value> 7 </init-param> 8 <init-param> 9 <param-name>listings</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 <load-on-startup>1</load-on-startup> 13 </servlet>
(1) 指定某一个目录或某几个目录
指定的目录必须在 webapp 下,比如 webapp/static 目录下及子目录下的所有文件由 DefaultServlet 按静态文件方式处理。
修改 webapp/WEB-INF/web.xml,添加如下配置:
1 <web-app> 2 3 ... 4 5 <servlet-mapping> 6 <servlet-name>default</servlet-name> 7 <url-pattern>/static/*</url-pattern> 8 <url-pattern>/static2/*</url-pattern> 9 ... 10 </servlet-mapping> 11 12 </web-app>
注:/static/* 表示指定 webapp/static 目录及子目录下所有文件
(2) 指定某一类或某几类文件
比如,指定 webapp 目录下及子目录下的所有 *.html 和 *.jpg 文件由 DefaultServlet 按静态文件方式处理。
修改 webapp/WEB-INF/web.xml,添加如下配置:
1 <web-app> 2 3 ... 4 5 <servlet-mapping> 6 <servlet-name>default</servlet-name> 7 <url-pattern>*.html</url-pattern> 8 <url-pattern>*.jpg</url-pattern> 9 ... 10 </servlet-mapping> 11 12 </web-app>
注:*.html 表示 webapp 目录及子目录下所有 *.html 文件
2) 配置 springmvc-beans.xml (Spring MVC 配置文件)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-4.0.xsd 10 http://www.springframework.org/schema/mvc 11 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 12 13 <!-- 设置 WebApp 整个目录支持静态资源 --> 14 <mvc:default-servlet-handler /> 15 16 <!-- 指定静态资源目录 --> 17 <mvc:resources location="/static/" mapping="/static/**" /> 18 19 ... 20 </beans>
(1) 配置 <mvc:default-servlet-handler />
设置 WebApp 整个目录支持静态资源
(2) 配置 <mvc:resources /> 的几种方式:
a) 指定目录及其各级子目录下的任意类型文件
<mvc:resources location="/static/" mapping="/static/**" />
b) 指定目录(不包含子目录)下的任意类型文件
<mvc:resources location="/static/" mapping="/static/*" />
c) 指定目录及其各级子目录下的某一类型文件
<mvc:resources location="/static/" mapping="/static/**/*.html" />
e) 指定目录(不包含子目录)下的某一类型文件
<mvc:resources location="/static/" mapping="/static/*.html" />
使用 <mvc:resources /> 时,就不需要使用 <mvc:default-servlet-handler />,因为 <mvc:default-servlet-handler /> 会让 <mvc:resources /> 的设置没有意义。
配置 web.xml 或配置 springmvc-beans.xml,选其中一种配置就行,在 Spring MVC 框架下的程序里,建议使用配置 springmvc-beans.xml 来指定静态资源目录.
示例
在 “Spring基础知识(12)- Spring MVC (二)” 的示例里,更新过 springmvc-beans.xml 的 SpringmvcBasic 项目基础上,修改如下。
1) 创建 src/main/webapp/WEB-INF/jsp/login.jsp 文件
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 2 <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> 3 <html> 4 <head> 5 <meta charset="UTF-8"> 6 <title>Login</title> 7 </head> 8 <body> 9 10 <h2>Login</h2> 11 12 <hr/> 13 <p>通过处理方法的形参接收请求参数</p> 14 <form:form method="POST" action="/user/login/post"> 15 <table> 16 <tr> 17 <td><form:label path="username">Username:</form:label></td> 18 <td><form:input path="username" value="admin" /></td> 19 </tr> 20 <tr> 21 <td><form:label path="password">Password:</form:label></td> 22 <td><form:input path="password" value="123456" /></td> 23 </tr> 24 <tr> 25 <td colspan="2"> 26 <input type="submit" value="Submit"/> 27 </td> 28 </tr> 29 </table> 30 </form:form> 31 32 <hr/> 33 <p>通过 HttpServletRequest 接收请求参数</p> 34 <form:form method="POST" action="/user/login/post2"> 35 <table> 36 <tr> 37 <td><form:label path="username">Username:</form:label></td> 38 <td><form:input path="username" value="admin" /></td> 39 </tr> 40 <tr> 41 <td><form:label path="password">Password:</form:label></td> 42 <td><form:input path="password" value="123456" /></td> 43 </tr> 44 <tr> 45 <td colspan="2"> 46 <input type="submit" value="Submit"/> 47 </td> 48 </tr> 49 </table> 50 </form:form> 51 52 <hr/> 53 <p>通过 @PathVariable 接收 URL 中的请求参数</p> 54 <p><a href="/user/login/post3/admin/123456">Click to Login</a></p> 55 56 <hr/> 57 <p>通过 @RequestParam 接收请求参数</p> 58 <form:form method="POST" action="/user/login/post4"> 59 <table> 60 <tr> 61 <td><form:label path="username">Username:</form:label></td> 62 <td><form:input path="username" value="admin" /></td> 63 </tr> 64 <tr> 65 <td><form:label path="password">Password:</form:label></td> 66 <td><form:input path="password" value="123456" /></td> 67 </tr> 68 <tr> 69 <td colspan="2"> 70 <input type="submit" value="Submit"/> 71 </td> 72 </tr> 73 </table> 74 </form:form> 75 76 <hr/> 77 <p>通过实体 Bean 接收请求参数</p> 78 <form:form method="POST" action="/user/login/post5"> 79 <table> 80 <tr> 81 <td><form:label path="username">Username:</form:label></td> 82 <td><form:input path="username" value="admin" /></td> 83 </tr> 84 <tr> 85 <td><form:label path="password">Password:</form:label></td> 86 <td><form:input path="password" value="123456" /></td> 87 </tr> 88 <tr> 89 <td colspan="2"> 90 <input type="submit" value="Submit"/> 91 </td> 92 </tr> 93 </table> 94 </form:form> 95 96 <hr/> 97 <p>通过 @ModelAttribute 接收请求参数</p> 98 <form:form method="POST" action="/user/login/post6"> 99 <table> 100 <tr> 101 <td><form:label path="username">Username:</form:label></td> 102 <td><form:input path="username" value="admin" /></td> 103 </tr> 104 <tr> 105 <td><form:label path="password">Password:</form:label></td> 106 <td><form:input path="password" value="123456" /></td> 107 </tr> 108 <tr> 109 <td colspan="2"> 110 <input type="submit" value="Submit"/> 111 </td> 112 </tr> 113 </table> 114 </form:form> 115 116 </body> 117 </html>
2) 创建 src/main/java/com/example/entity/User.java 文件
1 package com.example.entity; 2 3 public class User { 4 private int id; 5 private String username; 6 private String password; 7 8 public User() { 9 10 } 11 12 public int getId() { 13 return id; 14 } 15 16 public void setId(int id) { 17 this.id = id; 18 } 19 20 public String getUsername() { 21 return this.username; 22 } 23 24 public void setUsername(String username) { 25 this.username = username; 26 } 27 28 public String getPassword() { 29 return password; 30 } 31 32 public void setPassword(String password) { 33 this.password = password; 34 } 35 }
3) 创建 src/main/java/com/example/controller/UserController.java 文件
1 package com.example.controller; 2 3 import javax.servlet.http.HttpServletRequest; 4 5 import org.springframework.ui.Model; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import org.springframework.web.bind.annotation.PathVariable; 11 import org.springframework.web.bind.annotation.ModelAttribute; 12 import org.springframework.web.servlet.ModelAndView; 13 14 import com.example.entity.User; 15 16 @Controller 17 @RequestMapping("/user") 18 public class UserController { 19 20 @RequestMapping(value = "/login", method = RequestMethod.GET) 21 public ModelAndView getRegister() { 22 return new ModelAndView("login", "command", new User()); 23 } 24 25 @RequestMapping(value="/login/post", method=RequestMethod.POST) 26 public String loginPost(String username, String password, Model model) { 27 if ("admin".equals(username) && "123456".equals(password)) { 28 model.addAttribute("message", "success - 通过处理方法的形参接收请求参数"); 29 return "success"; 30 } else { 31 model.addAttribute("message", "failed - 通过处理方法的形参接收请求参数"); 32 return "failed"; 33 } 34 } 35 36 @RequestMapping(value="/login/post2", method=RequestMethod.POST) 37 public String loginPost2(HttpServletRequest request, Model model) { 38 String username = request.getParameter("username"); 39 String password = request.getParameter("password"); 40 41 if ("admin".equals(username) && "123456".equals(password)) { 42 model.addAttribute("message", "success - 通过 HttpServletRequest 接收请求参数"); 43 return "success"; 44 } else { 45 model.addAttribute("message", "failed - 通过 HttpServletRequest 接收请求参数"); 46 return "failed"; 47 } 48 } 49 50 @RequestMapping(value="/login/post3/{username}/{password}", method=RequestMethod.GET) 51 public String loginPost3(@PathVariable String username, @PathVariable String password, Model model) { 52 53 if ("admin".equals(username) && "123456".equals(password)) { 54 model.addAttribute("message", "success - 通过 @PathVariable 接收 URL 中的请求参数"); 55 return "success"; 56 } else { 57 model.addAttribute("message", "failed - 通过 @PathVariable 接收 URL 中的请求参数"); 58 return "failed"; 59 } 60 } 61 62 @RequestMapping("/login/post4") 63 public String loginPost4(@RequestParam String username, @RequestParam String password, Model model) { 64 65 if ("admin".equals(username) && "123456".equals(password)) { 66 model.addAttribute("message", "success - 通过 @RequestParam 接收请求参数"); 67 return "success"; 68 } else { 69 model.addAttribute("message", "failed - 通过 @RequestParam 接收请求参数"); 70 return "failed"; 71 } 72 } 73 74 @RequestMapping("/login/post5") 75 public String loginPost5(User user, Model model) { 76 77 if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) { 78 model.addAttribute("message", "success - 通过实体 Bean 接收请求参数"); 79 return "success"; 80 } else { 81 model.addAttribute("message", "failed - 通过实体 Bean 接收请求参数"); 82 return "failed"; 83 } 84 85 } 86 87 @RequestMapping("/login/post6") 88 public String loginPost6(@ModelAttribute("user") User user, Model model) { 89 90 if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) { 91 model.addAttribute("message", "success - 通过 @ModelAttribute 接收请求参数"); 92 return "success"; 93 } else { 94 model.addAttribute("message", "failed - 通过 @ModelAttribute 接收请求参数"); 95 return "failed"; 96 } 97 98 } 99 100 }
访问 http://localhost:9090/user/login