其他分享
首页 > 其他分享> > RESTful实现

RESTful实现

作者:互联网

RESTful实现

核心:url不变,通过请求方式来实现对资源的不同操作

痛点问题:仅有部分的浏览器支持发送put和delete请求方式

解决方式:设置请求方式处理过滤器

配置文件

<filter>
  <filter-name>mothedfilter</filter-name>
  <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>mothedfilter</filter-name>
  <url-pattern>/*</url-pattern>

HiddenHttpMethodFilter源码解析

org.springframework.web.filter.HiddenHttpMethodFilter
public class HiddenHttpMethodFilter extends OncePerRequestFilter {

  private static final List<String> ALLOWED_METHODS =
  枚举类型的,支持的请求方式的一个List,支持PUT,DELETE,PATCH三种
        Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
              HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
             

  /** 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 {

    HttpServletRequest requestToUse = request;
要想发送PUT,DELETE,PATCH的前提是,浏览器必须要发送POST请求
    if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
        从Request域对象中获取名为_method的参数,
        所有第二个要求来了,要求浏览器发送的请求里必必须要由名字为_method的参数(键是"_method",值是“PUT||DELETE||PATCH”)
        String paramValue = request.getParameter(this.methodParam);
       
        检查Request域对象中是否含有PUT||DELETE||PATCH
        if (StringUtils.hasLength(paramValue)) {
          String method = paramValue.toUpperCase(Locale.ENGLISH);
          if (ALLOWED_METHODS.contains(method)) {
          利用装饰器模式,生成一个wrapper对象,其实就只是重写了一个方法,getmethod方法
              requestToUse = new HttpMethodRequestWrapper(request, method);
             
          }
        }
    }

    filterChain.doFilter(requestToUse, 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;
    }
此后的get_method方法返回的就是由POST+Request域对象中的“_method”共同解析生成的PUT||DELETE||PATCH中的一个
    @Override
    public String getMethod() {
        return this.method;
    }
  }

CharacterEncodingFilter配置

<filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>  

 

多个filter执行的顺序:

由在web.xml文件中注册的一个先后顺序决定(书写顺序)

注意

在执行到CharacterEncodingFilter过滤器之前,不可以获取request域对象中的任何参数,不然CharacterEncodingFilter过滤器将会失效,但是HiddenHttpMethodFilter会获取reques域对象中的method参数,所以一定要将HiddenHttpMethodFilter过滤器注册在CharacterEncodingFilter之后

 

标签:String,实现,request,PATCH,methodParam,RESTful,method,CharacterEncodingFilter
来源: https://www.cnblogs.com/new228666/p/16391134.html