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;
}
}