SpringBoot入门建站全系列(二)Controller种类及映射处理详解
Controller及Mapping其实不属于SpringBoot,SpringBoot只是个大杂烩的容器而已。Controller及Mapping分别在Spring的web和context包中存在着。
本文主要介绍Controller种类及映射处理详解,并针对不同的写法做出示例。
品茗IT 提供在线支持:
如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。
一、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技术吧!