Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring引导控制器是否可以接收纯文本?_Java_Spring_Rest_Spring Boot - Fatal编程技术网

Java spring引导控制器是否可以接收纯文本?

Java spring引导控制器是否可以接收纯文本?,java,spring,rest,spring-boot,Java,Spring,Rest,Spring Boot,我试图用纯文本体(utf-8)处理POST请求,但spring似乎不喜欢调用的纯文本性质。可能是因为它不受支持,或者是因为我编码错误 @RestController @RequestMapping(path = "/abc", method = RequestMethod.POST) public class NlpController { @PostMapping(path= "/def", consumes = "text/plain; charset: utf-8", produc

我试图用纯文本体(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);
    }
}
text.txt包含纯文本(希伯来语的UTF-8)。

@rumbz 请参考下面的链接,它可能会解决您的问题

1使用注释
@RequestMapping(value=“/some path”,产生=
org.springframework.http.MediaType.TEXT(纯文本)
公共字符串plainTextAnnotation(){
返回“”;
}
其中,用您想要使用的任何内容替换/某些路径

2在响应实体的HTTP头中设置内容类型:
公共字符串plainTextResponseEntity(){
HttpHeaders HttpHeaders=新的HttpHeaders();
setContentType(org.springframework.http.MediaType.TEXT_PLAIN);
返回新的ResponseEntity(“”,httpHeaders,HttpStatus.OK);
}  

根据@m-deinum的评论:问题不在spring框架中,而是在curl向请求中添加了“application/x-www-form-urlencoded”

为了让这个问题更完整:

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

我想对spring是否支持text/plain这个问题的另一部分做一些解释

根据spring文档:@RequestMapping注释中的“消费”或消费媒体类型是什么

定义:

可消费媒体类型

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

可消费媒体类型表达式也可以如中所示求反!text/plain以匹配除内容类型为text/plain的请求以外的所有请求

spring如何实现媒体类型的内部匹配

Spring请求驱动的设计以一个名为dispatcher servlet的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);
    }
一旦媒体类型不匹配,此方法将返回false,getMatchingCondition将返回null,这将导致调用RequestMappingInfoHandlerMapping的handleNoMatch方法,并使用PartialMatchHelper类检查其不匹配的类型,如下所示,spring将抛出一次HttpMediaTypeNotSupportedException错误其see消耗不匹配

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));
    }
if(helper.hascoumesmitch()){
Set mediaTypes=helper.getConsumableMediaTypes();
MediaType contentType=null;
if(StringUtils.hasLength(request.getContentType())){
试一试{
contentType=MediaType.parseMediaType(request.getContentType());
}
捕获(InvalidMediaTypeException ex){
抛出新的HttpMediaTypeNotSupportedException(例如getMessage());
}
}
抛出新的HttpMediaTypeNotSupportedException(contentType,新的ArrayList(mediaTypes));
}

根据IANA,Spring支持所有媒体类型。问题只在于其他人引用的curl命令。

请添加您得到的错误。对于初学者,您可以删除
消费部分。您发送的不是纯文本,而是表单。这就是异常告诉您的。错误清楚地表明您正在发送表单。因此,您发送的请求具有错误的内容类型。您可以使用
curl-v…
验证
curl-d
将“…将导致curl使用内容类型应用程序/x-www-form-urlencoded”将数据传递到服务器,正如所解释的那样,curl发送的内容类型错误,因此不会在服务器上对其进行解析。我认为spring不支持与此无关,这取决于您(无论是否知情)发送请求的方式。根据CUrl文档,当您使用
--data binary
时,CUrl将始终使用
application/x-www-form-urlencoded
。该链接指向JSON请求(表单)。我需要处理纯文本+utf-8。很酷的答案!谢谢我想现在我明白了春天不是罪魁祸首。。。
curl -s -X POST -H "Content-Type:" -H "Content-Type: text/plain; charset: utf-8" --data-binary @file.txt localhost:8080/abc/def
@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
    // implementation omitted
}
    @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);
    }
     @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());
    }}
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));
    }