SpringMVC-简介+REST风格简介

1.SpringMVC是在原有的MVC结构上增加了 前端控制器 。前端控制器可以拦截所有请求,并对请求进行选择性派发。

   前端控制器是一个Servlet,因此需要在web.xml中进行配置

<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<!-- servlet启动加载,之前servlet是第一次访问时创建对象
		load-on-startup:服务器启动的时候创建对象,值越小优先级越高
		 -->
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Map all requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

2.前端控制器基本流程:

1>客户端通过点击链接发出请求:http://localhost:8080/springmvc/hello

2>Tomcat服务器接收到来自客户端的请求

3>SpringMVC的前端控制器接收所有请求

4>根据用户请求信息在IOC容器中查看与@RequestMapping中哪个方法标配,然后找到相应的类和方法。(@RequestMapping:是告诉SpringMVC哪些方法是用来处理请求,并且处理哪些请求。)

5>相应的方法处理后,返回一个值,前端控制器会认为该值是一个将要转发的页面地址

6>取到返回值之后,会经过视图解析器进行拼接,得到完整的地址

7>前端控制器根据完整地址转发到相应页面

3.@RequestMapping映射请求

(1)该注解可以放在方法上和类上:表示给该类中所有的方法都定义了基路径,因此当想要找到方法时,必须添加类的路径+方法路径

         如果只注解在方法上,则表示相对于类定义处的URL。(当客户端发出请求的href处可直接写注解中value的值)

(2)@ReauqetMapping的其他属性

          1>method:限定请求方式(例如method=RequestMethod.POST)

          2>params:规定请求参数

          3>headers:规定请求头(例如以下代码)

@RequestMapping(value="/testParamsAndHeaders",
params= {"username","age!=10"}, headers = { "Accept-Language=en-US,zh;q=0.8" })
//params中的值表示请求参数中必须带有username,且age不能为0
public String testParamsAndHeaders(){
System.out.println("testParamsAndHeaders...");
return "success";
}

(3) URL地址可以写模糊的匹配符:(精确和模糊路径下,精确路径优先)

       1> ?:可以替代任一个字符

       2> *:可以替代任意多个字符,和一层路径

       3> **:可以替代多层路径

(4)@PathVariable:可以获取某路径下占位符的值(代码如下)

//@PathVariable 注解可以将请求URL路径中的请求参数,传递到处理请求方法的入参中
@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable...id="+id);
return "success";
}

  4.SpringMVC支持REST风格,利用@RequestMapping中的参数实现REST风格

    REST:将客户端向服务器发送的所有请求都可以看作是一个资源,例如请求一个文本,文件,视频等等,都可以看作是一种资源。

                  对资源的操作本质上来说都是增删改查。以前写代码,对每个资源的增删改查都有相应的方法,getXXX(),deleteXXX()...  而REST风格指的就是通过URL地址和请求方式的结合来表示客户端将进行什么请求。

   但是由于原本在jsp中,客户端只能发送GET POST两种请求,因此还需要解决从页面发起PUT DELETE形式的请求问题。因此Spring中提供了对REST风格的支持。

/**
 * 1.测试REST风格的  GET,POST,PUT,DELETE 操作
 * 以CRUD为例:
 * 新增: /order POST
 * 修改: /order/1 PUT        update?id=1
 * 获取: /order/1 GET                get?id=1
 * 删除: /order/1 DELETE        delete?id=1
 
 * 2.如何发送PUT请求或DELETE请求?
 * ①.配置HiddenHttpMethodFilter
 * ②.需要发送POST请求
 * ③.需要在发送POST请求时携带一个 name="_method"的隐含域,值为PUT或DELETE
 
 * 3.在SpringMVC的目标方法中如何得到id值呢?
 *   使用@PathVariable注解
 */
@RequestMapping(value="/testRESTGet/{id}",method=RequestMethod.GET)
public String testRESTGet(@PathVariable(value="id") Integer id){
System.out.println("testRESTGet id="+id);
return "success";
}
 
@RequestMapping(value="/testRESTPost",method=RequestMethod.POST)
public String testRESTPost(){
System.out.println("testRESTPost");
return "success";
}
 
@RequestMapping(value="/testRESTPut/{id}",method=RequestMethod.PUT)
public String testRESTPut(@PathVariable("id") Integer id){
System.out.println("testRESTPut id="+id);
return "success";
}
 
@RequestMapping(value="/testRESTDelete/{id}",method=RequestMethod.DELETE)
public String testRESTDelete(@PathVariable("id") Integer id){
System.out.println("testRESTDelete id="+id);
return "success";
}

   (1)在web.xml中配置filter

<!-- 支持REST风格的过滤器:可以将POST请求转换为PUT或DELETE请求 -->
<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>

(2)在jsp中,首先创建一个post类型的表单,然后在该表单中设置一个_method的参数,对该参数进行赋值 value="delete"或者"put"

<fieldset>
<!-- 实验1 测试 REST风格 GET 请求 -->
<a href="springmvc/testRESTGet/1">testREST GET</a><br/><br/>
 
<!-- 实验2 测试 REST风格 POST 请求 -->
<form action="springmvc/testRESTPost" method="POST">
<input type="submit" value="testRESTPost">
</form>
 
<!-- 实验3 测试 REST风格 PUT 请求 -->
<form action="springmvc/testRESTPut/1" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="testRESTPut">
</form>
 
<!-- 实验4 测试 REST风格 DELETE 请求 -->
<form action="springmvc/testRESTDelete/1" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="testRESTDelete">
</form>
</fieldset>

   以上过程,主要都是在org.springframework.web.filter.HiddenHttpMethodFilter,因此查看其代码如下


public class HiddenHttpMethodFilter extends OncePerRequestFilter {

 

	/** Default method parameter: {@code _method} */

	public static final String DEFAULT_METHOD_PARAM = "_method";

 

	private String methodParam = DEFAULT_METHOD_PARAM;

 

 

	/**

	 * Set the parameter name to look for HTTP methods.

	 * @see #DEFAULT_METHOD_PARAM

	 */

	public void setMethodParam(String methodParam) {

		Assert.hasText(methodParam, "'methodParam' must not be empty");

		this.methodParam = methodParam;

	}

 

	@Override

	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

			throws ServletException, IOException {

 

		String paramValue = request.getParameter(this.methodParam);

		if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {

			String method = paramValue.toUpperCase(Locale.ENGLISH);
                        //将原先HttpRequest的getMethod方法重写
			HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
                        //此时就可以通过wrapper得到PUT DELETE的请求方式
			filterChain.doFilter(wrapper, response);

		}

		else {

			filterChain.doFilter(request, response);

		}

	}

 

 

	/**

	 * Simple {@link HttpServletRequest} wrapper that returns the supplied method for

	 * {@link HttpServletRequest#getMethod()}.

	 */

	private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {

 

		private final String method;

 

		public HttpMethodRequestWrapper(HttpServletRequest request, String method) {

			super(request);

			this.method = method;

		}

 

		@Override

		public String getMethod() {

			return this.method;

		}

	}

 

}
发布了27 篇原创文章 · 获赞 1 · 访问量 2014

猜你喜欢

转载自blog.csdn.net/yangyiyun199863/article/details/104991955