SpringMVC框架-RESTful

1.简介

  • REST:Representational State Transfer,表现层(即前端页面+控制层)资源状态转移(就是一种书写风格)

tips:

  • 资源是以名词为核心来组织的,即首先关注的是名词。一个资源可以由一个或多个URI来标识,URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互

2.实现

  • 四个表示操作方式的动词:GET、POST、PUT、DELETE
    • GET 用来获取资源
    • POST 用来新建资源
    • PUT 用来更新资源
    • DELETE用来删除资源
  • REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性:

在这里插入图片描述

<body>
<a th:href="@{/user}">查询所有用户信息</a>  # 超链接默认发送get请求
<a th:href="@{/user/1}">根据用户ID查询信息</a>
<form th:action="@{/user}" method="post">
    用户名: <input type="text" name="username"><br>
    密  码: <input type="password" name="password"><br>
    <input type="submit" value="提交"><br>
</form>
</body>
@Controller
public class UserController {
    /**
     * 使用RESTful模拟用户资源的CRUD
     * /user   GET 查询所有用户信息
     * /user/1 GET 根据用户ID查询信息
     * /user   POST 添加用户信息
     * /user/1 DELETE 根据用户ID删除用户信息
     * /user   PUT 修改用户信息
     */

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getAllUser(){
        return "success";
    }
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)  # 使用占位符接收传来的值
    public String getUserById(){
        return "success";
    }
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String insertUser(String username, String password){
        System.out.println("username:" + username);
        System.out.println("password:" + password);
        return "success";
    }
}

tips:

  • 使用<a th:href="@{/user}">后,Thymeleaf会自动加上上下文信息(即当前项目名称)。如果没有使用的话需要自己通过代码加上,比如在JSP页面中<a href="${pageContext.request.contextPath}/user}">

  • 由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?如果直接把form表单中的请求方式改为put并且把控制器方法中的method改为RequestMethod.GET是没有效果的(会变为发送get请求),需要先配置在web.xml中配置HiddenHttpMethodFilter

    # web.xml
    <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>
    
    <form th:action="@{/user}" method="post">
        <!--put写为大小写均可,源码中会转为大写-->
        <input type="hidden" name="_method" value="put">  
        用户名: <input type="text" name="username"><br>
        密  码: <input type="password" name="password"><br>
        <input type="submit" value="提交"><br>
    </form>
    
    @RequestMapping(value = "/user", method = RequestMethod.PUT)
    public String updateUser(String username, String password){
        System.out.println("username:" + username);
        System.out.println("password:" + password);
        return "success";
    }
    
    • SpringMVC 提供了 HiddenHttpMethodFilterPOST 请求转换为 DELETEPUT 请求

    • HiddenHttpMethodFilter 处理putdelete请求的条件:

      • 当前请求的请求方式必须为POST
      • 当前请求必须传输请求参数_method
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
          HttpServletRequest requestToUse = request;
          // 要求当前请求的请求方式必须为POST
          if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
              // this.methodParam就是_method
              String paramValue = request.getParameter(this.methodParam);
              if (StringUtils.hasLength(paramValue)) {
                  String method = paramValue.toUpperCase(Locale.ENGLISH);
                  // ALLOWED_METHODS =
      			//  Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(),
      			//	HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
                  if (ALLOWED_METHODS.contains(method)) {
                      // 把当前method替换当前request的原始method
                      requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                  }
              }
          }
          filterChain.doFilter((ServletRequest)requestToUse, response);
      }
      
  • web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter

    • CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字
      符集的,该方法要求前面不能有任何获取请求参数的操作,而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:String paramValue = request.getParameter(this.methodParam)

3.项目中常见问题

  • 添加了静态资源后重新部署还是无法访问:需要使用maven重新打包,这样war包中才会有静态资源,重新部署(让服务器执行war包)采用效果

  • 重新打包后还是访问不了静态资源:因为SpringMVC使用DispatcherServlet解析时会把<script type="text/javascript" th:src="@{/static/js/vue.js}">中的src添加上前后缀,此时需要在SpringMVC.xml文件中开放对静态资源的访问才能正确解析/static/js/vue.js/webapp/static/js/vue.js(即将当前请求交给默认的servlet处理)

// 开放对静态资源的访问
<mvc:default-servlet-handler/>
  • 如果只配置<mvc:default-servlet-handler/>不配置<mvc:annotation-driven />,则项目所有请求(不管是对静态资源的请求还是控制方法的请求)会被默认的servlet处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值