RESTful
RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。
RESTFul是一种软件架构风格,而不是标准。它只是提供了一种设计原则和约束条件,主要适用于客户端和服务端交互的软件。主要是基于HTTP协议实现。目的为了提高系统的可伸缩性,降低应用之间耦合度,方便框架分布式处理程序,基于这种风格可以使程序更加简单,具有层次感。
在RESTFul中,对用户请求的URL使用同一个URL而用不同的请求方法get/post/delete/put等方式的请求进行区分,这样方便前后端分离的开发,使得前端开发人员不会对请求的资源地址产生混淆,形成一个统一的接口。
使用规定
在HTTP协议中,四个表示操作方式的动词:GET/POST/PUT/DELETE,分别代表四种基本操作。其中GET用来请求资源,POST用来新建立资源,也可以是更新操作,PUT操作用来更新资源,DELETE操作用来删除资源。
GET
:对应select是从服务端进行查询,可以在服务器通过请求的参数区分查询方式。POST
:对应Create在服务器创建有一个资源,调用Insert操作。PUT
:对应update操作,在服务端更新资源,调用update操作。DELETE
:对应delete操作,在服务端进行删除资源调用delete语句。
对URL进行规范,用于编写RESTFul风格的URL:
- 非RESTFul风格UFL:
http://.../queryUserList?id=12&userName='sdf&sdf'
- Rest风格:
http://.../queryUserList/12
特点:URL简洁,可以将参数通过URL传递给服务端。
HTTP方法规范:不管是删除、修改、添加… 使用的URL是一致的,区分不同的删除等操作是通过HTTP的方法决定的。
- 例:
http://.../queryUserList/12
方法设置为delete是表示是删除12这个用户ID的信息,方法设置为get方法表示是查询用户ID为12的用户。
Spring MVC中实现RESTFul风格接口
Spring MVC对RESTFul应用提供以下支持:
- 使用
@RequestMapping
指定要处理的请求的URL和HTTP请求的动作类型。 - 利用
@PathVariable
注解将URL的变量映射到处理方法的参数上。 - 前端利用
ajax
,在客户端发出put,delete的动作要求。
例如:
<%--引入jquery:使用ajax提交数据--%>
<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"/>
<script type="text/javascript">
$(function () {
$("#btn").click(function () {
$.ajax({
contentType: " application/json;charset=UTF-8",
<%--JSON--%>
data: '{"id":1,"userName":"李四"}',
dataType: "json",
type: "post",
url: "${pageContext.request.contextPath }/user/responseJson"
})
}
)
});
</script>
/*
* 处理器
* 基于注解实现的Handler
*/
@Controller
public class ControllerDemo {
@RequestMapping("{id}")
public ModelAndView user(@PathVariable("id") int id) throws CustomException {
...
}
}
一般的应用格式如下:
@RequestMapping(value="/{id}",method=RequestMethod.GET)
@RequestMapping(value="/{id}",method=RequestMethod.POST)
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
@RequestMapping(value="/{id}",method=RequestMethod.PUT)
拦截器
Spring MVC中拦截器类似servlet开发中的拦截器。
自定义拦截器类
Spring MVC中的拦截器需要实现一个HandlerIntercepter
接口。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
*/
public class CustomInterceptor implements HandlerInterceptor {
//进入Handler之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
* true:表示放行
* false:表示拦截,不向下执行
*/
/**
* 应用场景:
* 用户身份认证,身份鉴权
* 如果认证不通过表示当前用户没有登录,需要次方法栏拦截不在往下执行
*/
System.out.println("进入Handler之前执行");
return true;
}
//进入Handler方法之后,返回ModelAndView之前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
/**
* 应用场景:
* 引用场景是将页面的公共的模型数据(菜单导航栏)传给视图,也可以是同一的指定视图
*/
System.out.println("进入Handler方法之后,返回ModelAndView之前执行");
}
//执行Handler之后执行此方法
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
/**
* 统一的异常处理或者是同一日志处理
*/
System.out.println("执行Handler之后执行此方法");
}
}
拦截器配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<!--配置Spring MVC的需要扫描注解的包路径-->
<context:component-scan base-package="com.test.contrller"/>
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--配置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--拦截器的配置-->
<mvc:interceptors>
<!--配置具体拦截器-->
<mvc:interceptor>
<!--
/** 表示所有的URL包含的子路径
/* 表示所有的URL的根路径
-->
<mvc:mapping path="/**"/>
<bean class="com.test.utils.CustomInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
执行结果
当preHandle
方法的返回值为false
时:
当preHandle
方法的返回值为true
时:
拦截器说明
-
Spring MVC拦截器是针对
HandlerMapping
进行拦截设置。 -
如果在某个
HandlerMapping
中配置拦截,经过该映射器拦截成功的Handler
会使用该拦截器。 -
Spring MVC配置类似全局的拦截器,将拦截器注入到每一个映射器中。
-
在配置多个拦截器时,一定要注意在配置中的顺序问题,例如统一的日志处理拦截器和登录认证拦截器。
- 统一的日志处理拦截器,
preHandle
一定是放行,且必须将他放在拦截器的第一个位置,而登录认证拦截器,应该放在第二个位置。
- 统一的日志处理拦截器,