gpt4 book ai didi

java - spring boot Controller 可以接收纯文本吗?

转载 作者:行者123 更新时间:2023-11-30 10:00:28 25 4
gpt4 key购买 nike

我正在尝试使用纯文本正文 (utf-8) 处理 POST 请求,但似乎 spring 不喜欢调用的纯文本性质。可能是它不受支持 - 或者,我是不是编码有误?

@RestController
@RequestMapping(path = "/abc", method = RequestMethod.POST)
public class NlpController {
@PostMapping(path= "/def", consumes = "text/plain; charset: utf-8", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> doSomething(@RequestBody String bodyText)
{
...
return ResponseEntity.ok().body(responseObject);
}
}

响应是:

已解决 [org.springframework.web.HttpMediaTypeNotSupportedException: 不支持内容类型 'application/x-www-form-urlencoded']

我用 curl 命令测试过:

curl -s -X POST -H 'Content-Type: text/plain; charset: utf-8' --data-binary @text.txt localhost:8080/abc/def

text.txt 包含纯文本(希伯来语中的 UTF-8)。

最佳答案

我想对 spring 是否支持 text/plain 的问题的另一部分进行一些说明?

根据 spring 文档:@RequestMapping 注解中的“consumes”或 Consumable Media Types 是什么

定义:

消费媒体类型

“您可以通过指定可消费媒体类型列表来缩小主映射。只有当 Content-Type 请求头与指定的媒体类型匹配时,请求才会被匹配。例如:”

@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
// implementation omitted
}

可消费的媒体类型表达式也可以像 !text/plain 一样被取反,以匹配除 Content-Type 为 text/plain 之外的所有请求。

spring内部是如何匹配媒体类型的?

Spring 请求驱动设计以称为调度程序 Servlet 的 servlet 为中心,它使用特殊的 bean 来处理请求,其中一个 bean 是 RequestMappingHandlerMapping,它使用ConsumesRequestCondition 类的 getMatchingCondition 方法如下所示。

    @Override
public ConsumesRequestCondition getMatchingCondition(ServerWebExchange exchange) {
if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
return PRE_FLIGHT_MATCH;
}
if (isEmpty()) {
return this;
}
Set<ConsumeMediaTypeExpression> result = new LinkedHashSet<>(expressions);
result.removeIf(expression -> !expression.match(exchange));
return (!result.isEmpty() ? new ConsumesRequestCondition(result) : null);
}

获取匹配条件类使用静态内部类ConsumesMediaType Expression 实际进行校验

     @Override
protected boolean matchMediaType(ServerWebExchange exchange) throws UnsupportedMediaTypeStatusException {
try {
MediaType contentType = exchange.getRequest().getHeaders().getContentType();
contentType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
return getMediaType().includes(contentType);
}
catch (InvalidMediaTypeException ex) {
throw new UnsupportedMediaTypeStatusException("Can't parse Content-Type [" +
exchange.getRequest().getHeaders().getFirst("Content-Type") +
"]: " + ex.getMessage());
}}

一旦媒体类型不匹配,此方法返回 false 并且 getMatchingCondition 返回 null,这导致调用 RequestMappingInfoHandlerMapping 的 handleNoMatch 方法并使用 PartialMatchHelper 类我们检查它具有什么类型的不匹配,如下所示,spring 抛出一次 HttpMediaTypeNotSupportedException 错误它看到消耗不匹配

if (helper.hasConsumesMismatch()) {
Set<MediaType> mediaTypes = helper.getConsumableMediaTypes();
MediaType contentType = null;
if (StringUtils.hasLength(request.getContentType())) {
try {
contentType = MediaType.parseMediaType(request.getContentType());
}
catch (InvalidMediaTypeException ex) {
throw new HttpMediaTypeNotSupportedException(ex.getMessage());
}
}
throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<>(mediaTypes));
}

Spring 根据 IANA https://www.iana.org/assignments/media-types/media-types.xhtml 支持所有媒体类型问题仅在于其他人引用的 curl 命令。

关于java - spring boot Controller 可以接收纯文本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57970995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com