SpringBoot入門建站全系列(二)Controller種類及映射處理詳解

SpringBoot入門建站全系列(二)Controller種類及映射處理詳解

Controller及Mapping其實(shí)不屬于SpringBoot,SpringBoot只是個(gè)大雜燴的容器而已。Controller及Mapping分別在Spring的web和context包中存在著。

本文主要介紹Controller種類及映射處理詳解,并針對(duì)不同的寫法做出示例。

品茗IT-SpringBoot專題-同步發(fā)布

品茗IT 提供在線支持:

一鍵快速構(gòu)建Spring項(xiàng)目工具

一鍵快速構(gòu)建SpringBoot項(xiàng)目工具

一鍵快速構(gòu)建SpringCloud項(xiàng)目工具

一站式Springboot項(xiàng)目生成

Mysql一鍵生成Mybatis注解Mapper

如果大家正在尋找一個(gè)java的學(xué)習(xí)環(huán)境,或者在開發(fā)中遇到困難,可以加入我們的java學(xué)習(xí)圈,點(diǎn)擊即可加入,共同學(xué)習(xí),節(jié)約學(xué)習(xí)時(shí)間,減少很多在學(xué)習(xí)中遇到的難題。

一、Controller種類

Controller可以簡(jiǎn)單分為RestController和Controller。RestController位于Spring的web包中,Controller還是在Spring的context包中。

1.1 Controller

控制器Controller 負(fù)責(zé)處理由DispatcherServlet 分發(fā)的請(qǐng)求。在這個(gè)時(shí)候,就先不考慮Model、ModelMap和ModelAndView之類的東東,大多數(shù)時(shí)候根本用不上這三個(gè)東東的,Spring提供的方法很簡(jiǎn)潔的,后面會(huì)一一講解。

@Controller注解的類,會(huì)作為訪問的路徑映射處理,不加特殊處理的返回值會(huì)被作為跳轉(zhuǎn)路徑。

1.2 RestController

就是@Controller + @ResponseBody 注解的綜合,返回值如果是實(shí)體,一般作為json數(shù)據(jù)返回,也可以定制返回值。

二、Mapping種類

RequestMapping是mapping的基本類型,另外還有GetMapping、PostMapping、PutMapping、DeleteMapping、PatchMapping。

2.1 RequestMapping

RequestMapping注解包含以下屬性:

name: 別名

value/path: 請(qǐng)求路徑

method:請(qǐng)求類型(get/post...)

params: 篩選參數(shù)

headers:篩選http header

consumes: 篩選content-type

produces: 返回值的content-type

2.2 GetMapping

等價(jià)于@RequestMapping(method = RequestMethod.GET),只處理http的get請(qǐng)求。

2.3 PostMapping

等價(jià)于@RequestMapping(method = RequestMethod.POST),只處理http的post請(qǐng)求。

2.4 PutMapping

等價(jià)于@RequestMapping(method = RequestMethod.PUT),只處理http的pus請(qǐng)求。

2.5 DeleteMapping

等價(jià)于@RequestMapping(method = RequestMethod.DELETE),只處理http的delete請(qǐng)求。

2.6 PatchMapping

等價(jià)于@RequestMapping(method = RequestMethod.PATCH),只處理http的patch請(qǐng)求。

2.7 Http不同方法的區(qū)別

冪等: 如果一個(gè)方法重復(fù)執(zhí)行多次,產(chǎn)生的效果是一樣的,那就是冪等的。冪等的意思是如果相同的操作再執(zhí)行第二遍第三遍,結(jié)果還是一樣。

RESTful架構(gòu)應(yīng)該遵循統(tǒng)一接口原則,統(tǒng)一接口包含了一組受限的預(yù)定義的操作,不論什么樣的資源,都是通過使用相同的接口進(jìn)行資源的訪問。接口應(yīng)該使用標(biāo)準(zhǔn)的HTTP方法如GET,PUT和POST,并遵循這些方法的語義。

如果按照HTTP方法的語義來暴露資源,那么接口將會(huì)擁有安全性和冪等性的特性,例如GET和HEAD請(qǐng)求都是安全的, 無論請(qǐng)求多少次,都不會(huì)改變服務(wù)器狀態(tài)。而GET、HEAD、PUT和DELETE請(qǐng)求都是冪等的,無論對(duì)資源操作多少次, 結(jié)果總是一樣的,后面的請(qǐng)求并不會(huì)產(chǎn)生比第一次更多的影響。

RESTful其實(shí)還是http,只是定義了一種http請(qǐng)求的規(guī)范,我們?nèi)绻凑者@個(gè)規(guī)范來了,它就是RESTful,如果不按照這個(gè)規(guī)范來,就不能稱之為RESTful。比如,我們?cè)贕ET請(qǐng)求里做了新建或更新,那它就不是冪等的,事實(shí)上,我們一般只是用到了GET和POST請(qǐng)求,PUT、PATCH、DELETE一般都沒用上,都是用GET/POST來完成這些操作了,而且沒毛病,不過最好是按照RESTful的要求來寫,比如elasticsearch就有一套很規(guī)范的RESTful Api。

RESTful風(fēng)格主要用到以下幾種:

GET: 獲取數(shù)據(jù)。

POST: POST方法不是冪等的,多次執(zhí)行,將導(dǎo)致多條相同的條目被創(chuàng)建。

PUT: PUT方法一般會(huì)用來更新一個(gè)已知資源,冪等。

PATCH:是對(duì)PUT方法的補(bǔ)充,用來對(duì)已知資源進(jìn)行局部更新,PATCH是冪等的。

DELETE: 刪除操作。

三、Request參數(shù)獲取方法種類

對(duì)請(qǐng)求的參數(shù)獲取,一般有以下幾種方式:

3.1 RequestBody

請(qǐng)求體body作為字符串進(jìn)行解析,一般是是json或者xml。

3.2 RequestParam

請(qǐng)求參數(shù)為鍵值對(duì),請(qǐng)求方式可以為GET請(qǐng)求的key=xx&value=xx形式,也可以是post的form或x-www-form-urlencoded

3.3 RequestPart

作用類似于RequestParam,但是更強(qiáng)大,復(fù)雜的請(qǐng)求,如一個(gè)formdata中,包含一個(gè)文件和一個(gè)json,這時(shí)用RequestParam只能解析出文件和一個(gè)json字符串,用RequestPart可以解析出文件和實(shí)體。

3.4 RequestHeader

可以把Request請(qǐng)求header部分的值綁定到方法的參數(shù)上.

3.5 CookieValue

顧名思義,獲取cookie值。

3.6 PathVariable

請(qǐng)求路徑中的某一部分。

3.7 ModelAttribute

運(yùn)用在參數(shù)上,會(huì)將客戶端傳遞過來的參數(shù)按名稱注入到指定對(duì)象中,并且會(huì)將這個(gè)對(duì)象自動(dòng)加入ModelMap中。

運(yùn)用在方法上,會(huì)在每一個(gè)@RequestMapping標(biāo)注的方法前執(zhí)行,如果有返回值,則自動(dòng)將該返回值加入到ModelMap中。

反正沒用過。

3.8 RequestAttribute

獲取Request作用域下塞入的Attribute屬性。

3.9 SessionAttribute

獲取Session作用域下塞入的Attribute屬性。

四、示例

4.1 請(qǐng)求跳轉(zhuǎn)

默認(rèn)跳轉(zhuǎn)方式就是forward。

forward和redirect的不同就是,redirect是302,地址欄會(huì)變化的,顯示最新請(qǐng)求地址。forward不會(huì)變。

@Controller
@RequestMapping("/web")
public class HelloWorldWeb {

    @RequestMapping(value = "/hello")
    public String test() {
        return "/index.html";
    }

        @RequestMapping(value = "/hello1")
    public String test1() {
        return "forward:/index.html";
    }
    
    @RequestMapping(value = "/hello2")
    public String test2() {
        return "redirect:/index.html";
    }

}

4.2 請(qǐng)求json/xml,返回json/xml

根據(jù)下面的測(cè)試情況可以看出,不指定produces,默認(rèn)都是返回json。不指定consumes和produces的情況下,可以根據(jù)請(qǐng)求數(shù)據(jù)類型做解析,默認(rèn)都是返回json。

要想返回xml,或支持xml數(shù)據(jù),需要添加依賴:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-xml-provider</artifactId>
</dependency>

同名路徑允許存在,但請(qǐng)求信息應(yīng)不同,比如請(qǐng)求數(shù)據(jù)為json/xml的不同。

@PostMapping和@RequestMapping功能一樣,但是@PostMapping只支持POST請(qǐng)求,@RequestMapping不指定請(qǐng)求類型的時(shí)候,是可以捕獲所有類型的請(qǐng)求。

@RestController
@RequestMapping("/test")
public class HelloWorldRest {

    @RequestMapping(value = "/hello")
    public String test() {
        return "hello,world";
    }
    @RequestMapping(value = "/testJsonx")
    public TestClass hellox(@RequestBody TestClass json) {
        return json;
    }
    @RequestMapping(value = "/testResXml",consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_XML_VALUE)
    public TestClass hello(@RequestBody TestClass json) {
        return json;
    }
    @PostMapping(value = "/test",consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
    public TestClass hello1(@RequestBody TestClass json) {
        return json;
    }
    
    @RequestMapping(value = "/test",consumes=MediaType.APPLICATION_XML_VALUE, produces=MediaType.APPLICATION_XML_VALUE)
    public TestClass hello2(@RequestBody TestClass json) {
        return json;
    }
    @RequestMapping(value = "/testReqJson",consumes=MediaType.APPLICATION_XML_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
    public TestClass hello3(@RequestBody TestClass json) {
        return json;
    }
    
    public static class TestClass{
        String key;
        String value;
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }

}

4.3 跳轉(zhuǎn)和json/xml共存

只需在需要返回json/xml的實(shí)體上加上ResponseBody即可。

@Controller
@RequestMapping("/web")
public class HelloWorldWeb {

    @RequestMapping(value = "/hello")
    public String test() {
        return "/index.html";
    }
    
    @RequestMapping(value = "/testJsonx")
    @ResponseBody
    public TestClass hellox(@RequestBody TestClass json) {
        return json;
    }
}

4.4 各種參數(shù)獲取方式示例

@RestController
@RequestMapping("/all")
public class HelloWorldALLRest {

    /**
     * 測(cè)試json請(qǐng)求
     * @param json
     * @return
     */
    @PostMapping(value = "/testJson")
    public TestClass hellox(@RequestBody TestClass json) {
        return json;
    }

    /**
     * 測(cè)試獲取url參數(shù)
     * @param json
     * @return
     */
    @GetMapping(value = "/testBody")
    public TestClass testBody(TestClass json) {
        return json;
    }

    /**
     * 測(cè)試獲取key-value的參數(shù)值
     * @param key
     * @return
     */
    @GetMapping(value = "/testParam")
    public String testParam(@RequestParam("key") String key) {
        return key;
    }

    /**
     * 測(cè)試獲取路徑
     * @param id
     * @return
     */
    @GetMapping(value = "/testParam/{id}")
    public String helloxx(@PathVariable("id") String id) {
        return id;
    }

    /**
     * 測(cè)試獲取參數(shù)
     * @param key
     * @return
     */
    @GetMapping(value = "/testAttr")
    public String testAttr(@ModelAttribute("key") String key) {
        return key;
    }

    /**
     * 測(cè)試RequestPart功能
     * @param file
     * @param testClass
     * @return
     */
    @PostMapping(value = "/testPart")
    public TestClass testPart(@RequestPart("file") MultipartFile file, @RequestPart("testClass") TestClass testClass) {
        return testClass;
    }

    /**
     * 測(cè)試文件自動(dòng)填充
     * @param testClassMutiPart
     * @return
     */
    @PostMapping(value = "/testMultipart")
    public TestClassMutiPart testMultipart(TestClassMutiPart testClassMutiPart) {
        return testClassMutiPart;
    }

    /**
     * 測(cè)試http頭自動(dòng)填充
     * @param type
     * @return
     */
    @GetMapping(value = "/testHeader")
    public String testHeader(@RequestHeader("Connection") String type) {
        return type;
    }

    /**
     * 測(cè)試cookie信息自動(dòng)填充
     * @param JSESSIONID
     * @return
     */
    @GetMapping(value = "/testCookie")
    public String testCookie(@CookieValue("JSESSIONID") String JSESSIONID) {
        return JSESSIONID;
    }

    /**
     * 測(cè)試session的屬性值獲取
     * @param test
     * @param http
     * @return
     */
    @GetMapping(value = "/testSession")
    public String testSession(@SessionAttribute(value = "test", required = false) String test,
            HttpServletRequest http) {
        http.getSession().setAttribute("test", "asdasd");
        return test;
    }

    /**
     * 測(cè)試requst的屬性值獲取,需要一個(gè)跳轉(zhuǎn)到本路徑的請(qǐng)求做配置,或者中途對(duì)requst做過修改也可以。
     * @param test
     * @return
     */
    @GetMapping(value = "/testReqAttr")
    public String testReqAttr(@RequestAttribute(value = "test", required = false) String test) {
        return test;
    }

    /**
     * 測(cè)試用內(nèi)部類,寫成外部類也可以
     * @author fufei
     *
     */
    public static class TestClass {
        String key;
        String value;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
    /**
     * 測(cè)試用內(nèi)部類,寫成外部類也可以
     * @author fufei
     *
     */
    public static class TestClassMutiPart {
        String key;
        String value;
        MultipartFile file;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public MultipartFile getFile() {
            return file;
        }

        public void setFile(MultipartFile file) {
            this.file = file;
        }

    }
}
    喜歡這篇文章么,喜歡就[加入我們的Java學(xué)習(xí)圈(點(diǎn)擊加入或下方掃碼)](https://jq.qq.com/?_wv=1027&k=52sgH1J)一起討論SpringBoot技術(shù)吧!
    ![品茗IT技術(shù)交流群](https://upload-images.jianshu.io/upload_images/15296705-b024ad1fce668926.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring的模型-視圖-控制器(MVC)框架是圍繞一個(gè)DispatcherServlet來設(shè)計(jì)的,這個(gè)Servl...
    alexpdh閱讀 2,746評(píng)論 0 3
  • 對(duì)于java中的思考的方向,1必須要看前端的頁面,對(duì)于前端的頁面基本的邏輯,如果能理解最好,不理解也要知道幾點(diǎn)。 ...
    神尤魯?shù)婪?/span>閱讀 907評(píng)論 0 0
  • SpringMVC介紹 Spring web mvc 和Struts2都屬于表現(xiàn)層的框架,它是Spring框架的一...
    day_Sunny閱讀 901評(píng)論 0 0
  • 1、Spring MVC請(qǐng)求流程 (1)初始化:(對(duì)DispatcherServlet和ContextLoderL...
    拾壹北閱讀 2,021評(píng)論 0 12
  • 昏黃的落葉紛紛揚(yáng)揚(yáng)地,恣肆在胡說大街上,道路兩旁鮮少可見的路燈,歪著脖子畏畏縮縮地吐出微弱的光,光不像光,倒像黑夜...
    吳何閱讀 640評(píng)論 3 7

友情鏈接更多精彩內(nèi)容