美文网首页SpringBoot专题
SpringBoot入门建站全系列(二)Controller种类

SpringBoot入门建站全系列(二)Controller种类

作者: 逍遥天扬 | 来源:发表于2019-04-26 17:08 被阅读65次

    SpringBoot入门建站全系列(二)Controller种类及映射处理详解

    Controller及Mapping其实不属于SpringBoot,SpringBoot只是个大杂烩的容器而已。Controller及Mapping分别在Spring的web和context包中存在着。

    本文主要介绍Controller种类及映射处理详解,并针对不同的写法做出示例。

    品茗IT-SpringBoot专题-同步发布

    品茗IT 提供在线支持:

    一键快速构建Spring项目工具

    一键快速构建SpringBoot项目工具

    一键快速构建SpringCloud项目工具

    一站式Springboot项目生成

    Mysql一键生成Mybatis注解Mapper

    一、Controller种类

    Controller可以简单分为RestController和Controller。RestController位于Spring的web包中,Controller还是在Spring的context包中。

    1.1 Controller

    控制器Controller 负责处理由DispatcherServlet 分发的请求。在这个时候,就先不考虑Model、ModelMap和ModelAndView之类的东东,大多数时候根本用不上这三个东东的,Spring提供的方法很简洁的,后面会一一讲解。

    @Controller注解的类,会作为访问的路径映射处理,不加特殊处理的返回值会被作为跳转路径。

    1.2 RestController

    就是@Controller + @ResponseBody 注解的综合,返回值如果是实体,一般作为json数据返回,也可以定制返回值。

    二、Mapping种类

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

    2.1 RequestMapping

    RequestMapping注解包含以下属性:

    name: 别名

    value/path: 请求路径

    method:请求类型(get/post...)

    params: 筛选参数

    headers:筛选http header

    consumes: 筛选content-type

    produces: 返回值的content-type

    2.2 GetMapping

    等价于@RequestMapping(method = RequestMethod.GET),只处理http的get请求。

    2.3 PostMapping

    等价于@RequestMapping(method = RequestMethod.POST),只处理http的post请求。

    2.4 PutMapping

    等价于@RequestMapping(method = RequestMethod.PUT),只处理http的pus请求。

    2.5 DeleteMapping

    等价于@RequestMapping(method = RequestMethod.DELETE),只处理http的delete请求。

    2.6 PatchMapping

    等价于@RequestMapping(method = RequestMethod.PATCH),只处理http的patch请求。

    2.7 Http不同方法的区别

    幂等: 如果一个方法重复执行多次,产生的效果是一样的,那就是幂等的。幂等的意思是如果相同的操作再执行第二遍第三遍,结果还是一样。

    RESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。

    如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。而GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。

    RESTful其实还是http,只是定义了一种http请求的规范,我们如果按照这个规范来了,它就是RESTful,如果不按照这个规范来,就不能称之为RESTful。比如,我们在GET请求里做了新建或更新,那它就不是幂等的,事实上,我们一般只是用到了GET和POST请求,PUT、PATCH、DELETE一般都没用上,都是用GET/POST来完成这些操作了,而且没毛病,不过最好是按照RESTful的要求来写,比如elasticsearch就有一套很规范的RESTful Api。

    RESTful风格主要用到以下几种:

    GET: 获取数据。

    POST: POST方法不是幂等的,多次执行,将导致多条相同的条目被创建。

    PUT: PUT方法一般会用来更新一个已知资源,幂等。

    PATCH:是对PUT方法的补充,用来对已知资源进行局部更新,PATCH是幂等的。

    DELETE: 删除操作。

    三、Request参数获取方法种类

    对请求的参数获取,一般有以下几种方式:

    3.1 RequestBody

    请求体body作为字符串进行解析,一般是是json或者xml。

    3.2 RequestParam

    请求参数为键值对,请求方式可以为GET请求的key=xx&value=xx形式,也可以是post的form或x-www-form-urlencoded

    3.3 RequestPart

    作用类似于RequestParam,但是更强大,复杂的请求,如一个formdata中,包含一个文件和一个json,这时用RequestParam只能解析出文件和一个json字符串,用RequestPart可以解析出文件和实体。

    3.4 RequestHeader

    可以把Request请求header部分的值绑定到方法的参数上.

    3.5 CookieValue

    顾名思义,获取cookie值。

    3.6 PathVariable

    请求路径中的某一部分。

    3.7 ModelAttribute

    运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中。

    运用在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中。

    反正没用过。

    3.8 RequestAttribute

    获取Request作用域下塞入的Attribute属性。

    3.9 SessionAttribute

    获取Session作用域下塞入的Attribute属性。

    四、示例

    4.1 请求跳转

    默认跳转方式就是forward。

    forward和redirect的不同就是,redirect是302,地址栏会变化的,显示最新请求地址。forward不会变。

    @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 请求json/xml,返回json/xml

    根据下面的测试情况可以看出,不指定produces,默认都是返回json。不指定consumes和produces的情况下,可以根据请求数据类型做解析,默认都是返回json。

    要想返回xml,或支持xml数据,需要添加依赖:

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

    同名路径允许存在,但请求信息应不同,比如请求数据为json/xml的不同。

    @PostMapping和@RequestMapping功能一样,但是@PostMapping只支持POST请求,@RequestMapping不指定请求类型的时候,是可以捕获所有类型的请求。

    @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 跳转和json/xml共存

    只需在需要返回json/xml的实体上加上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 各种参数获取方式示例

    @RestController
    @RequestMapping("/all")
    public class HelloWorldALLRest {
    
        /**
         * 测试json请求
         * @param json
         * @return
         */
        @PostMapping(value = "/testJson")
        public TestClass hellox(@RequestBody TestClass json) {
            return json;
        }
    
        /**
         * 测试获取url参数
         * @param json
         * @return
         */
        @GetMapping(value = "/testBody")
        public TestClass testBody(TestClass json) {
            return json;
        }
    
        /**
         * 测试获取key-value的参数值
         * @param key
         * @return
         */
        @GetMapping(value = "/testParam")
        public String testParam(@RequestParam("key") String key) {
            return key;
        }
    
        /**
         * 测试获取路径
         * @param id
         * @return
         */
        @GetMapping(value = "/testParam/{id}")
        public String helloxx(@PathVariable("id") String id) {
            return id;
        }
    
        /**
         * 测试获取参数
         * @param key
         * @return
         */
        @GetMapping(value = "/testAttr")
        public String testAttr(@ModelAttribute("key") String key) {
            return key;
        }
    
        /**
         * 测试RequestPart功能
         * @param file
         * @param testClass
         * @return
         */
        @PostMapping(value = "/testPart")
        public TestClass testPart(@RequestPart("file") MultipartFile file, @RequestPart("testClass") TestClass testClass) {
            return testClass;
        }
    
        /**
         * 测试文件自动填充
         * @param testClassMutiPart
         * @return
         */
        @PostMapping(value = "/testMultipart")
        public TestClassMutiPart testMultipart(TestClassMutiPart testClassMutiPart) {
            return testClassMutiPart;
        }
    
        /**
         * 测试http头自动填充
         * @param type
         * @return
         */
        @GetMapping(value = "/testHeader")
        public String testHeader(@RequestHeader("Connection") String type) {
            return type;
        }
    
        /**
         * 测试cookie信息自动填充
         * @param JSESSIONID
         * @return
         */
        @GetMapping(value = "/testCookie")
        public String testCookie(@CookieValue("JSESSIONID") String JSESSIONID) {
            return JSESSIONID;
        }
    
        /**
         * 测试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;
        }
    
        /**
         * 测试requst的属性值获取,需要一个跳转到本路径的请求做配置,或者中途对requst做过修改也可以。
         * @param test
         * @return
         */
        @GetMapping(value = "/testReqAttr")
        public String testReqAttr(@RequestAttribute(value = "test", required = false) String test) {
            return test;
        }
    
        /**
         * 测试用内部类,写成外部类也可以
         * @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;
            }
        }
        /**
         * 测试用内部类,写成外部类也可以
         * @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;
            }
    
        }
    }
    
        喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot技术吧!
        ![品茗IT技术交流群](https://img.haomeiwen.com/i15296705/b024ad1fce668926.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    相关文章

      网友评论

        本文标题:SpringBoot入门建站全系列(二)Controller种类

        本文链接:https://www.haomeiwen.com/subject/vmyqnqtx.html