微信扫一扫

028-83195727 , 15928970361
business@forhy.com

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>


二:RequestMapping处理请求

1)@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法,请求参数及请求头映射请求。

2)@RequestMappingvaluemethodparamsheaders分别表示请求URL、请求方法、请求参数及请求头的

     映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。

3)paramsheaders支持简单的表达式

param1:表示请求必须包含名为param1的请求参数。

!param1:表示请求不能包含名为param1的请求参数。

param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1

param1==value1:表示请求包含名为param1的请求参数,但其值必须为value1

{"param1=value","param2"}:请求必须包含名为param1param2的两个请求参数,且param1参数的值

必须为value1

@RequestMapping指定请求方式:

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>

@RequestMapping指定请求头和请求参数(需要了解,用的机会比较少)

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>

@RequestMapping支持Ant类型的通配符



示例:
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>


三:@RequestMapping@PathVariable的使用

@PathVariable映射URL绑定的占位符

1)带占位符的URLSpring3.0新增的功能,该功能在Spring MVCREST目标挺进发展过程中具有

里程碑的意义。

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

四:SpringMVCREST

REST

Representational State Transfer(资源)表现层状态转化。是目前最流行的一种互联网软件架构

 它结构清晰、符合标准、易于理解、扩展方便。所以正得到越来越多网站的采用

资源:

Resources,网络上的一个实体,或者说是网络上的一个具体信息,它可以是一段文本,一张图片,

  一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,没种资源

  对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI即为每一个资源的独一无二的识

  别符。

表现层:

Representation,把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如文本可以用

      txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式。

状态转化:

State Transfer,每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议是一个无

状态协议,即所有的状态都保存在服务器端。因此如果客户端想要操作服务器,就必须通过某种

手段让服务器端发送"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"

表现层状态转化"。具体说就是HTTP协议里面,四个表示操作的动词:GETPOSTPUTDELETE

它们分别对应四种基本操作:GET用来获取资源、POST用来新建资源、PUT用来更新资源、DELETE

用来删除资源。

HiddenHttpMethodFilter

由于浏览器form表单只支持GETPOST请求,而DELETEPUTmethod并不支持,

Spring3.0添加了一个过滤器,可以将这些请求转换为便准的HTTP方法,

使得支持GETPOSTPUTDELETE请求。

示例:

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