Controller中常用的注解
@RestController() 和 @Controller()
@RestController 注解将 @Controller 和 @ResponseBody 注解合二为一,这会应用于该类中定义的所有端点
@ResponseBody 和 ResponseEntity
@ResponseBody是一个Spring MVC注解,用于指示方法的返回值应该被直接写入HTTP响应体。这通常用于处理返回非HTML内容的请求,如JSON或XML。
@GetMapping("/users/{userId}")
@ResponseBody
public User getUser(@PathVariable Long userId) {
// 根据userId获取用户信息
return userService.getUserById(userId);
}
在这个例子中,@ResponseBody注解确保了方法返回的User对象被直接序列化为JSON或XML格式,并写入HTTP响应体中。
@ResponseBody注解的核心在于其与Spring MVC的HttpMessageConverter接口的协同工作,该接口定义了返回值与HTTP响应体之间的转换逻辑。
与 @ResponseBody 相反,ResponseEntity 是一种通用类型,代表整个 HTTP 响应。因此,可以控制其中的任何内容:HTTP状态码、HTTP Header 和 HTTP Body。
设置自定义标头:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set")
如果将一个对象放入:
@GetMapping("/hello")
public ResponseEntity<String> hello() {
return new ResponseEntity<>(new User(‘jdon’), HttpStatus.OK);
}
Consumes & Produces & Accept & Content-Type
上面的4个属性,首先分为2类:
- Accept 和 Content-Type 属于 Client方配置的header;
- Consumes 和 Produces 属于Server方配置的header;
consumes 属性指定 Controller 可接受的媒体类型,可以有多个。
@RequestMapping(value = "/greetings", method = RequestMethod.POST, consumes="application/json")
public void addGreeting(@RequestBody ContentType type, Model model) {
}
produces 指定 Controller 发送回客户端的媒体类型,这也是一个列表,可以指定多个。如果系统不能按照这个媒体类型响应资源,则会响应 “406 Not Acceptable” 错误。
@GetMapping(
value = "/greetings-with-response-body",
produces="application/json"
)
public String getGreetingWhileReturnTypeIsString() {
return "{\"test\": \"Hello\"}";
}
Accept代表发送端(客户端)希望接受的数据类型。
比如:Accept:text/xml;
代表客户端希望接受的数据类型是xml类型
Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。
比如:Content-Type:text/html;
代表发送端发送的数据格式是html。
对应的java类
// org.springframework.http.MediaType
static {
// Not using "valueOf' to avoid static init cost
ALL = new MediaType("*", "*");
APPLICATION_ATOM_XML = new MediaType("application", "atom+xml");
APPLICATION_CBOR = new MediaType("application", "cbor");
APPLICATION_FORM_URLENCODED = new MediaType("application", "x-www-form-urlencoded");
APPLICATION_GRAPHQL = new MediaType("application", "graphql+json");
APPLICATION_JSON = new MediaType("application", "json");
APPLICATION_JSON_UTF8 = new MediaType("application", "json", StandardCharsets.UTF_8);
APPLICATION_NDJSON = new MediaType("application", "x-ndjson");
APPLICATION_OCTET_STREAM = new MediaType("application", "octet-stream");
APPLICATION_PDF = new MediaType("application", "pdf");
APPLICATION_PROBLEM_JSON = new MediaType("application", "problem+json");
APPLICATION_PROBLEM_JSON_UTF8 = new MediaType("application", "problem+json", StandardCharsets.UTF_8);
APPLICATION_PROBLEM_XML = new MediaType("application", "problem+xml");
APPLICATION_RSS_XML = new MediaType("application", "rss+xml");
APPLICATION_STREAM_JSON = new MediaType("application", "stream+json");
APPLICATION_XHTML_XML = new MediaType("application", "xhtml+xml");
APPLICATION_XML = new MediaType("application", "xml");
IMAGE_GIF = new MediaType("image", "gif");
IMAGE_JPEG = new MediaType("image", "jpeg");
IMAGE_PNG = new MediaType("image", "png");
MULTIPART_FORM_DATA = new MediaType("multipart", "form-data");
MULTIPART_MIXED = new MediaType("multipart", "mixed");
MULTIPART_RELATED = new MediaType("multipart", "related");
TEXT_EVENT_STREAM = new MediaType("text", "event-stream");
TEXT_HTML = new MediaType("text", "html");
TEXT_MARKDOWN = new MediaType("text", "markdown");
TEXT_PLAIN = new MediaType("text", "plain");
TEXT_XML = new MediaType("text", "xml");
}
Get请求的Content-type
需要注意的是,一般get请求不需要设置Content-Type,只有post才有必要设置!
为什么get请求不需要设置Content-Type?
那要从Content-Type的作用说起,Content-Type作用是为了告诉别人我携带的数据是什么格式?
对于request请求
get是不携带数据的,url中?后的参数不算做data
post是需要带参数的,也就是data参数,客户端告诉服务端,自己的数据类型
对于get请求,在url地址中携带的参数,在服务端,使用@RequestParam
来接收。
虽然,get请求不需要指定Content-Type,但是如果url地址中携带的参数,包含一些特殊字符或者中文等,此时就需要使用cn.hutool.core.net.url.UrlBuilder
来构建有效的url地址。
UrlBuilder previewUrlBuilder = UrlBuilder.of().setCharset(StandardCharsets.UTF_8).setScheme(directAccessProperties.getScheme())
.setHost(directAccessProperties.getHost()).setPort(directAccessProperties.getPort())
.addPath(FileUploadConstants.PREVIEW_URL_PREFIX)
.addQuery(FileUploadConstants.COMPANY_ID_STR, companyId).addQuery(FileUploadConstants.ID_STR, fileListQueryRespDTO.getId())
.addQuery(IotSecurityConstant.TOKEN_ID_PARAMETER, loginUserProvider.getLoginUser().getId());
Post请求,Client各Content-type与Server的接收参数的方式
常见的content-type,有以下几种:
- application/x-www-form-urlencoded
- application/json;charset=UTF-8
- multipart/form-data
针对上面的几种content-type,在server端,接收参数的方式,分别如下:
1.content-type是application/json;charset=UTF-8,在server端,使用@RequestBody
来接收数据
2.content-type是application/x-www-form-urlencoded,在server端,使用@RequestParam
来接收数据 或者 直接使用对象
来接收,不加任何注解
3.content-type是multipart/form-data,在server端,使用@RequestPart
来接收数据.
在处理复杂请求时,@RequestPart 注解是一个非常有用的工具。它允许我们同时处理文件上传和其他表单数据。
在使用 @RequestPart 时,可以指定参数名来提取请求中的文件和数据。例如,@RequestPart("file") 用于提取文件,@RequestPart("jsonData") 用于提取 JSON 数据。