Spring MVC 学习3:@RequestMapping注解和REST
mvc,spring mvc,框架2016-10-30
<span style="font-family: SimSun; font-size: 10.5pt; background-color: rgb(255, 255, 255);">一:RequestMapping修饰类</span>
Spring MVC使用@RequestMapping注解为控制器指定可以处理那些URL请求。
@RequestMapping既可以修饰方法也可修饰类。
既修饰类又修饰方法的示例:
package com.springmvc.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * 1:@RequestMapping不但可以修饰方法,还可以修饰类 * 2:修饰类:相当于提供初步的请求映射信息,相对于WEB应用的根目录 * 修饰方法:提供进一步的细分映射信息,如果只是修饰方法,相当于类定义出的URL * 则方法处标记的URL相对于WEB应用的根目录。 * @return */ @RequestMapping("/requestMappingInClass") public String RequestMappingInClassTest(){ System.out.println("RequestMappingInClass"); return SUCCESS; } }
<span style="font-family: SimSun; font-size: 10.5pt; background-color: rgb(255, 255, 255);"> </span>
<span style="font-family: SimSun; font-size: 10.5pt; background-color: rgb(255, 255, 255);"> JSP页面: <a href="springmvc/requestMappingInClass">requestMappingInClass</a> <span style="white-space:pre"> </span>其中springmvc表示修饰类的@RequestMapping("/springmvc") </span><span style="font-family: SimSun; font-size: 10.5pt; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>其中</span><span style="font-size: 10.5pt; font-family: Calibri; background-color: rgb(255, 255, 255);">/requestMappingInClass</span><span style="font-family: SimSun; font-size: 10.5pt; background-color: rgb(255, 255, 255);">表示修饰方法的</span><span style="font-size: 10.5pt; font-family: Calibri; background-color: rgb(255, 255, 255);">@RequestMapping("/requestMappingInClass")</span>
如果@RequestMapping只修饰方法,那么JSP页面的写法为:
<ahref="requestMappingInClass">requestMappingInClass</a>
1)@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法,请求参数及请求头映射请求。
2)@RequestMapping的value、method、params及headers分别表示请求URL、请求方法、请求参数及请求头的
映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。
3)params和headers支持简单的表达式
param1:表示请求必须包含名为param1的请求参数。
!param1:表示请求不能包含名为param1的请求参数。
param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1
param1==value1:表示请求包含名为param1的请求参数,但其值必须为value1
{"param1=value","param2"}:请求必须包含名为param1和param2的两个请求参数,且param1参数的值
必须为value1
Java代码:
package com.springmvc.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * 使用Method属性来指定请求的方式 * @return */ @RequestMapping(value="/requestMappingWithMethod",method=RequestMethod.POST) public String RequestMappingWithMethod(){ System.out.println("RequestMappingWithMethod"); return SUCCESS; } }
<span style="white-space:pre"> </span>由于在类中指定了请求方式为POST,那么jsp页面提交的方式必须为POST,否则会报错,不能使用超链接的形式来发送请求
<span style="white-space:pre"> </span>JSP代码:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 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=ISO-8859-1"> <title>Insert title here</title> </head> <body> <form action="springmvc/requestMappingWithMethod" method="post"> <input type="submit" /> </form> </body> </html>
package com.springmvc.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * params指定的含义是:这条请求的参数中必须有username和参数age,并且age不等于10。 * headers指定的含义是:请求头信息中Accept-Language的值必须为zh-CN,zh;q=0.8 * 作用:更加精确的映射请求 * @return */ @RequestMapping(value="/requestMappingWithParamAndHeader",
<span style="white-space:pre"> </span>params={"username","age!=10"},headers={"Accept-Language=en-US,zh;q=0.8"}) public String RequestMappingWithParamAndHeader(){ System.out.println("RequestMappingWithParamAndHeader"); return SUCCESS; } }JSP页面:
<pre name="code" class="html"><%@ page language="java" contentType="text/html; charset=ISO-8859-1" 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=ISO-8859-1"> <title>Insert title here</title> </head> <body> <a href="springmvc/requestMappingWithParamAndHeader?username=test&age=11">
<span style="white-space:pre"> </span>RequestMappingWithParamAndHeader</a> </body> </html>
示例:
Java代码:
<span style="white-space:pre"> </span><pre name="code" class="java">package com.springmvc.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * "*"表示在requestMappingInAnt和ant之间可以为任意值 * 做简单了解 * @return */ @RequestMapping("/requestMappingInAnt/*/ant") public String RequestMappingInAnt(){ System.out.println("RequestMappingInAnt"); return SUCCESS; } }JSP页面:
<pre name="code" class="html"><%@ page language="java" contentType="text/html; charset=ISO-8859-1" 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=ISO-8859-1"> <title>Insert title here</title> </head> <body> <!-- 中间路径"aaaaa"可以为任意 --> <a href="springmvc/requestMappingInAnt/aaaaa/ant">RequestMappingInAnt</a> </body> </html>
@PathVariable映射URL绑定的占位符
1)带占位符的URL是Spring3.0新增的功能,该功能在Spring MVC向REST目标挺进发展过程中具有
里程碑的意义。
2)通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中:URL中的{XXX}
占位符可以通过@PathVariable("XXX")绑定到操作方法的入参中。
示例:
Java代码:
package com.springmvc.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * @PathVariable可以映射URL中占位符到目标方法的参数中 * @param id * @return */ @RequestMapping("/requestMappinAndPathVariable/{id}") public String RequestMappinAndPathVariable(@PathVariable("id") Integer id){ System.out.println("RequestMappinAndPathVariable:"+id); return SUCCESS; } }JSP页面:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 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=ISO-8859-1"> <title>Insert title here</title> </head> <body> <a href="springmvc/requestMappinAndPathVariable/102"> RequestMappinAndPathVariable</a> </body> </html>
<span style="white-space:pre"> </span>运行之后可在控制台输出id为102
即Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构
它结构清晰、符合标准、易于理解、扩展方便。所以正得到越来越多网站的采用
即Resources,网络上的一个实体,或者说是网络上的一个具体信息,它可以是一段文本,一张图片,
一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,没种资源
对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI即为每一个资源的独一无二的识
别符。
即Representation,把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如文本可以用
txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式。
即State Transfer,每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议是一个无
状态协议,即所有的状态都保存在服务器端。因此如果客户端想要操作服务器,就必须通过某种
手段让服务器端发送"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"
表现层状态转化"。具体说就是HTTP协议里面,四个表示操作的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET用来获取资源、POST用来新建资源、PUT用来更新资源、DELETE
用来删除资源。
由于浏览器form表单只支持GET和POST请求,而DELETE和PUT等method并不支持,
Spring3.0添加了一个过滤器,可以将这些请求转换为便准的HTTP方法,
使得支持GET、POST、PUT与DELETE请求。
示例:
Step1:在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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>springmvc-1</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置org.springframework.web.filter.HiddenHttpMethodFilter: 可以把POST请求转为DELETE或者PUT请求 --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <!-- 设置过滤所有请求 --> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置DispatcherServlet --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置DispatcherServlet的第一个初始化参数:配置SpringMVC配置文件的位置与名称 --> <!-- 实际上也可以不通过contextConfigLocation来配置SpringMVC的配置文件, 如果使用 默认的,那么默认的配置文件的路径为:/WEB-INF/<servlet-name>-servlet.xml 本例中默认的配置文件为"/WEB-INF/springDispatcherServlet-servlet.xml" --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!--标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。 1标示在启动的时候会加载这个Servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <!-- "/"代表是处理任何请求都会被应答,也可以指定特别的请求("*.text"表示任何text结尾的请求会被应答) --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
<span style="font-family: Arial, Helvetica, sans-serif;"> Step2:在JSP中定义不同的请求 </span>
<span style="font-family: Arial, Helvetica, sans-serif;"><%@ page language="java" contentType="text/html; charset=ISO-8859-1"</span>
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=ISO-8859-1"> <title>Insert title here</title> </head> <body> <!-- DELETE和PUT请求的原始请求类型都为POST请求 --> <!-- 测试REST的PUT请求 --> <form action="springmvc/requestMappingREST/1" method="post"> <!-- HiddenHttpMethodFilter拦截器会根据你请求参数_method为PUT把请求类型改为PUT --> <input type="hidden" name="_method" value="PUT" /> <input type="submit" value="REST PUT" /> </form> <br /> <br /> <!-- 测试REST的DELETE请求 --> <form action="springmvc/requestMappingREST/1" method="post"> <!-- HiddenHttpMethodFilter拦截器会根据你请求参数_method为DELETE把请求类型改为DELETE -->
<!-- 设置隐藏域,便于拦截器修改请求类型 --><input type="hidden" name="_method" value="DELETE" />
<span style="white-space:pre"> </span><input type="submit" value="REST DELETE" /> </form> <br /> <br /> <!-- 测试REST的POST请求 --> <form action="springmvc/requestMappingREST" method="post"> <input type="submit" value="REST POST" /> </form> <br /> <br /> <!-- 测试REST的GET请求 --> <a href="springmvc/requestMappingREST/1">REST GET</a> </body>
<span style="font-family: Arial, Helvetica, sans-serif;"> Step3:在Java代码中声明不同请求的Handler </span><span style="font-family: Arial, Helvetica, sans-serif;">package com.springmvc.test;</span>
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @RequestMapping("/springmvc") @Controller public class RequestMappingInClass { private static final String SUCCESS = "success"; /** * REST风格的URL * 以CRUD为例 * REST 老式请求 * 新增订单:/order post * 修改订单:/order/1 PUT update?id=1 * 查询订单:/order/1 GET get?id=1 * 删除订单:/order/1 DELETE delete?id=1 * * 如何发送PUT和DELETE请求: * 1.配置过滤器 * 2.需要发送POST请求 * 3.在发送POST请求时,携带一个name="_method"的隐藏域,值为DELETE或PUT * 在SpringMVC中使用@PathVariable获取id * @param id * @return */ @RequestMapping(value="/requestMappingREST/{id}",method=RequestMethod.PUT) public String RequestMappingRESTPUT(@PathVariable("id") Integer id){ System.out.println("REST PUT id:"+id); return SUCCESS; } @RequestMapping(value="/requestMappingREST/{id}",method=RequestMethod.DELETE) public String RequestMappingRESTDelete(@PathVariable("id") Integer id){ System.out.println("REST DELETE id:"+id); return SUCCESS; } @RequestMapping(value="/requestMappingREST",method=RequestMethod.POST) public String RequestMappingREST(){ System.out.println("REST POST"); return SUCCESS; } @RequestMapping(value="/requestMappingREST/{id}",method=RequestMethod.GET) public String RequestMappingREST(@PathVariable("id") Integer id){ System.out.println("REST GET:"+id); return SUCCESS; } }