胖哥學SpringMVC:請求方式轉換過濾器配置

@RequestMapping

我的建議從新練習一遍搭建的過程,若是感受麻煩你能夠直接複製上一個工程,可是須要修改pom.xml中的一點信息php

<groupId>com.hanpang.springmvc</groupId>
<artifactId>springmvc-demo02</artifactId>
<version>0.0.1-SNAPSHOT</version>
複製代碼

1.請求路徑相同問題

看下面的代碼,我設置了相同的路徑,那麼會有說明錯誤呢?請本身查看控制檯信息html

package com.hanpang.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller//告知其是一個控制器
@RequestMapping("/cms")
public class Demo05Controller {
	@RequestMapping(value="/user")
	public ModelAndView test01() {
		System.out.println("用於獲取用戶信息");
		return null;
	}
	@RequestMapping(value="/user")
	public ModelAndView test02() {
		System.out.println("用於修改用戶信息");
		return null;
	}
}
複製代碼

錯誤信息以下:java

Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'demo05Controller' method 
public org.springframework.web.servlet.ModelAndView com.hanpang.web.Demo05Controller.test02()
to {[/cms/user]}: There is already 'demo05Controller' bean method
public org.springframework.web.servlet.ModelAndView com.hanpang.web.Demo05Controller.test01() mapped.
複製代碼

在一個控制器名字叫demo05Controller的中有一個映射路徑"/cms/user"對應了兩個方法,屬於模糊映射web

若是出現了這樣的狀況或者需求,如何處理呢? 咱們能夠設置requestMethod來區別相同路徑的不一樣處理方式spring

2.method屬性的設置

能夠經過設置method設置能夠處理,我的推薦這種方式.安全

package com.hanpang.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller//告知其是一個控制器
@RequestMapping("/cms")
public class Demo05Controller {
	@RequestMapping(value="/user",method=RequestMethod.GET)
	public ModelAndView test01() {
		System.out.println("用於獲取用戶信息");
		return null;
	}
	@RequestMapping(value="/user",method=RequestMethod.POST)
	public ModelAndView test02() {
		System.out.println("用於修改用戶信息");
		return null;
	}
}
複製代碼

啓動正常,區分你的請求方式執行相應的方法mvc

問題:咱們知道的是HTML發送的請求方式有且僅有GET和POST?app

HTTP Method Conversion
A key principle of REST is the use of the Uniform Interface. This means that all resources (URLs) can be manipulated using the same four HTTP methods: GET, PUT, POST, and DELETE. For each method, the HTTP specification defines the exact semantics. For instance, a GET should always be a safe operation, meaning that is has no side effects, and a PUT or DELETE should be idempotent, meaning that you can repeat these operations over and over again, but the end result should be the same. While HTTP defines these four methods, HTML only supports two: GET and POST. Fortunately, there are two possible workarounds: you can either use JavaScript to do your PUT or DELETE, or simply do a POST with the 'real' method as an additional parameter (modeled as a hidden input field in an HTML form). This latter trick is what Spring’s HiddenHttpMethodFilter does. This filter is a plain Servlet Filter and therefore it can be used in combination with any web framework (not just Spring MVC). Simply add this filter to your web.xml, and a POST with a hidden _method parameter will be converted into the corresponding HTTP method request.
複製代碼

來自官網的處理方案框架

REST的一個關鍵原則是使用統一接口。這意味着全部資源(url)均可以使用相同的4個HTTP方法進行操做:GET、PUT、POST和DELETE。對於每一個方法,HTTP規範定義了精確的語義。例如,GET應該始終是一個安全的操做,這意味着沒有反作用,PUT或DELETE應該是冪等的,這意味着您能夠一次又一次地重複這些操做,可是最終結果應該是相同的。雖然HTTP定義了這四種方法,可是HTML只支持兩種方法:GET和POST。幸運的是,有兩種可能的解決方案:要麼使用JavaScript進行PUT或DELETE,要麼使用「real」方法做爲附加參數(將其建模爲HTML表單中的隱藏輸入字段)。後一種技巧是Spring的HiddenHttpMethodFilter所作的。這個過濾器是一個普通的Servlet過濾器,所以它能夠與任何web框架(不單單是Spring MVC)結合使用。只需將這個過濾器添加到您的web中。xml,以及帶有隱藏方法參數的POST將被轉換成相應的HTTP方法請求。
複製代碼

Spiring Web MVC 中提供了八種請求方式,可是經常使用的是官方推薦的四種,分別是jsp

  • GET 查詢操做
  • POST 添加操做
  • PUT 修改操做
  • DELETE 刪除操做

3.配置測試過程

  • (1) 測試代碼以下

    package com.hanpang.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller//告知其是一個控制器
    @RequestMapping("/cms")
    public class Demo05Controller {
    	@RequestMapping(value="/user",method=RequestMethod.GET)
    	public ModelAndView test01() {
    		System.out.println("用於獲取用戶信息");
    		return null;
    	}
    	@RequestMapping(value="/user",method=RequestMethod.POST)
    	public ModelAndView test02() {
    		System.out.println("用於添加用戶信息");
    		return null;
    	}
    	@RequestMapping(value="/user",method=RequestMethod.PUT)
    	public ModelAndView test03() {
    		System.out.println("用於修改用戶信息");
    		return null;
    	}
    	@RequestMapping(value="/user",method=RequestMethod.DELETE)
    	public ModelAndView test04() {
    		System.out.println("用於刪除用戶信息");
    		return null;
    	}
    }
    複製代碼
  • (2) 配置HiddenHttpMethodFilter過濾器

    註解配置:

    package com.hanpang.config;
    
    import javax.servlet.Filter;
    import org.springframework.web.filter.HiddenHttpMethodFilter;
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    
    public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    	@Override
    	protected Class<?>[] getRootConfigClasses() {
    		return new Class[] {WebConfig.class};
    	}
    
    	@Override
    	protected Class<?>[] getServletConfigClasses() {
    		return null;
    	}
    
    	@Override
    	protected String[] getServletMappings() {
    		return new String[] {"/"};
    	}
    	//看這裏重寫方法,新增過濾器
    	@Override
    	protected Filter[] getServletFilters() {
    		HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
    		return new Filter[] {hiddenHttpMethodFilter};
    	}
    }
    複製代碼

    XML配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" >
        <filter>
            <filter-name>httpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>httpMethodFilter</filter-name>
            <!-- 請注意這裏Servlet過濾器 -->
            <servlet-name>mvc</servlet-name>
        </filter-mapping>
    
        <servlet>
            <servlet-name>mvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>2</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>mvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
        <welcome-file-list>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    </web-app>
    複製代碼
  • (3)使用Postman測試

    POST是真正的請求方式,傳遞一個"_method"名的參數,賦值爲PUT或者DELETE(不區分大小寫),看控制檯執行的方法

相關文章
相關標籤/搜索