RESTful
概述
1、软件风格架构
2、REST:Representational State Transfer,表现层资源状态转移
3、资源
(1)将服务器看作是由很多离散的资源组成,每个资源是服务器上一个可命名的抽象概念
(2)与面向对象设计类似,资源是以名词为核心组织
(3)一个资源可以由一个或多个 URI 来标识,URI 既是资源的名称,也是资源在 Web 上的地址
(4)客户端可以通过资源的URI与其进行交互
4、资源的表述
(1)一段对于资源在某个特定时刻的状态的描述,可以在客户端 <-> 服务器端之间转移(交换)
(2)多种格式,例如:HTML / XML / JSON / 纯文本 / 图片 / 视频 / 音频等,通过协商机制来确定
(3)请求 - 响应方向的表述通常使用不同的格式
5、状态转移
(1)在客户端和服务器端之间转移代表资源状态的表述
(2)通过转移和操作资源的表述来间接实现操作资源的目的
实现
1、HTTP 协议中,四个基本操作
(1)GET:获取资源
(2)POST:新建资源
(3)PUT:更新资源
(4)DELETE:删除资源
2、REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为URL地址的一部分,以保证整体风格的一致性
3、示例
操作 | 原始方式 | REST 风格 |
查询 | getUserById?id=1 | get 请求:user/1 |
保存 | saveUser | post 请求:user |
删除 | deleteUser?id=1 | delete 请求:user/1 |
更新 | updateUser | put 请求:user |
设置 PUT / DELETE
1、.html 页面 form 标签 method 属性只能是 get / post,不填写 / 其他,则默认为 get
2、解决
(1)jQuery.ajax(url,[settings]),settings:选项,type:String,请求方式("POST" / "GET"), 默认为 "GET",其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持
(2)HiddenHttpMethodFilter
HiddenHttpMethodFilter
1、web.xml 配置过滤器
<!-- 配置HiddenHttpMethodFilter -->
<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、源码
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
private static final List<String> ALLOWED_METHODS =
Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = 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 {
//request是当前被拦截的请求
HttpServletRequest requestToUse = request;
//为POST请求时,进入if
if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
//paramValue为_method属性的值
String paramValue = request.getParameter(this.methodParam);
//paramValue不为空 / 长度不为0,进入if
if (StringUtils.hasLength(paramValue)) {
//paramValue转换大写,赋值method
String method = paramValue.toUpperCase(Locale.ENGLISH);
//请求若为PUT、DELETE、PATCH之一,进入if
if (ALLOWED_METHODS.contains(method)) {
//由POST请求,转换为其他请求
requestToUse = new HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter(requestToUse, response);
}
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
//原生Request(post)通过装饰器模式,包装为其他请求
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
}
}
3、不使用 AJAX 情况下,需要表单发送 POST 请求
(1)form 标签,method 属性值为 post
(2)隐藏域,_method 属性值为请求:put、delete、patch 之一(不区分大小写)
(3)put 请求
<form method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="提交put请求">
</form>
(4)delete 请求
<!-- 使用超链接提交delete请求 -->
<a th:href="@{/控制器方法路径/}+${被删除的信息特征}">delete</a>
<form method="post">
<input type="hidden" name="_method" value="delete">
</form>
4、Filter 按照配置顺序执行,CharacterEncodingFilter 必须在获取任何请求参数之前执行,否则失效
5、springMVC.xml
(1)开放对静态资源的访问
<mvc:default-servlet-handler/>
(2)当配置 default-servlet-handler,而不配置 annotation-driven,那么所有请求都将交给 DefaultServlet 处理,DispatcherServlet 将失效
(3)当配置 default-servlet-handler,同时配置 annotation-driven,那么所有请求将先交给 DispatcherServlet 处理,若不能处理,请求由 DefaultServletHttpRequestHandler 交给 DefaultServlet 处理
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战