Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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
Spring 如何在HTTP状态代码之后添加自定义消息_Spring_Spring Mvc_Spring Boot - Fatal编程技术网

Spring 如何在HTTP状态代码之后添加自定义消息

Spring 如何在HTTP状态代码之后添加自定义消息,spring,spring-mvc,spring-boot,Spring,Spring Mvc,Spring Boot,我使用SpringBoot作为web服务器,有时我想响应[HTTP/1.1403xxx] 我用@ResponseStatus和response.senderro(403,“XXX”)尝试了ResponseEntity,但嗅探数据包发现只有web服务器响应[HTTP/1.1 403] 卷曲示例: [root@localhost ~]# curl -v 192.168.12.36:8080/test * About to connect() to 192.168.12.36 port 8080 (#

我使用SpringBoot作为web服务器,有时我想响应[HTTP/1.1403xxx]

我用
@ResponseStatus
response.senderro(403,“XXX”)
尝试了
ResponseEntity
,但嗅探数据包发现只有web服务器响应[HTTP/1.1 403]

卷曲示例:

[root@localhost ~]# curl -v 192.168.12.36:8080/test
* About to connect() to 192.168.12.36 port 8080 (#0) 
*   Trying 192.168.12.36...
* Connected to 192.168.12.36 (192.168.12.36) port 8080 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.12.36:8080
> Accept: */*
> 
< HTTP/1.1 403 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 09 Aug 2018 08:26:37 GMT
< 
* Connection #0 to host 192.168.12.36 left intact
[root@localhost#curl-v 192.168.12.36:8080/测试
*即将连接()到192.168.12.36端口8080(#0)
*正在尝试192.168.12.36。。。
*连接到192.168.12.36(192.168.12.36)端口8080(#0)
>获取/测试HTTP/1.1
>用户代理:curl/7.29.0
>主持人:192.168.12.36:8080
>接受:*/*
> 
我需要的答复是:

< HTTP/1.1 403 XXX
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
...

如何在HTTP状态代码后添加自定义消息?

您可以在注释上设置原因:

@ResponseStatus(value = HttpStatus.FORBIDDEN, reason="You custom reason")

您可以在注释上设置原因:

@ResponseStatus(value = HttpStatus.FORBIDDEN, reason="You custom reason")

您可以让HTTP响应的主体包含一条消息,您可以使用任何附加信息来解析该消息

状态代码(在响应中)上的HTTP状态消息可以是您想要的任何内容,并且不会影响任何客户端。HTTP客户端通常忽略消息文本

这里有一个替代方案。创建接受状态代码和消息的常规异常。然后创建一个异常处理程序。使用异常处理程序从异常中检索信息并返回给服务的调用者

然后使用异常处理程序检索信息并将其返回给服务调用方

@ControllerAdvice
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(ResourceException.class)
    public ResponseEntity handleException(ResourceException e) {
        // log exception 
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }         
} 
然后在需要时创建一个异常

throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource.");

您可以让HTTP响应的主体包含一条消息,您可以使用任何附加信息来解析该消息

状态代码(在响应中)上的HTTP状态消息可以是您想要的任何内容,并且不会影响任何客户端。HTTP客户端通常忽略消息文本

这里有一个替代方案。创建接受状态代码和消息的常规异常。然后创建一个异常处理程序。使用异常处理程序从异常中检索信息并返回给服务的调用者

然后使用异常处理程序检索信息并将其返回给服务调用方

@ControllerAdvice
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(ResourceException.class)
    public ResponseEntity handleException(ResourceException e) {
        // log exception 
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }         
} 
然后在需要时创建一个异常

throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource.");

您在问题中没有这样说,但我猜您正在使用Tomcat。默认情况下,Tomcat只发送状态代码,不发送原因短语。原因短语是HTTP规范的可选部分,因此我不建议依赖它来发送

如果您确实希望依赖自定义原因短语,而不是像其他答案所建议的那样使用响应正文,那么您必须配置Tomcat以发送原因短语(只有Tomcat 8.5支持的内容),或者切换到另一个容器。对于SpringBoot支持的嵌入式servlet容器,Jetty和Undertow都会发送原因短语

下面是一个小示例,它将Tomcat配置为发送原因短语并启用自定义短语的使用:

package sample.tomcat;

import javax.servlet.http.HttpServletResponse;

import org.apache.coyote.AbstractProtocol;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@SpringBootApplication
public class SampleTomcatApplication {

    @Bean
    public EmbeddedServletContainerCustomizer tomcatCustomizer() {
        return (container) -> {
            if (container instanceof TomcatEmbeddedServletContainerFactory) {
                ((TomcatEmbeddedServletContainerFactory) container)
                        .addConnectorCustomizers((connector) -> {
                            ((AbstractProtocol<?>) connector.getProtocolHandler())
                                    .setSendReasonPhrase(true);
                        });
            }
        };
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER", "true");
        SpringApplication.run(SampleTomcatApplication.class, args);
    }

}

@Controller
class SampleController {

    @GetMapping("/")
    public void customReasonPhrase(HttpServletResponse response) throws Exception {
        response.setStatus(503, "Custom");
    }

}
package sample.tomcat;
导入javax.servlet.http.HttpServletResponse;
导入org.apache.coyote.AbstractProtocol;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
导入org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
导入org.springframework.context.annotation.Bean;
导入org.springframework.stereotype.Controller;
导入org.springframework.web.bind.annotation.GetMapping;
@SpringBoot应用程序
公共类抽样应用程序{
@豆子
公共嵌入式ServletContainerCustomizer tomcatCustomizer(){
退货(集装箱)->{
if(TomcatEmbeddedServletContainerFactory的容器实例){
((TomcatEmbeddedServletContainerFactory)容器)
.addConnectorCustomizers((连接器)->{
((AbstractProtocol)connector.getProtocolHandler())
.SetSendReason短语(正确);
});
}
};
}
公共静态void main(字符串[]args)引发异常{
System.setProperty(“org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER”,“true”);
run(SampleTomcatApplication.class,args);
}
}
@控制器
类采样控制器{
@GetMapping(“/”)
public void customReasonPhrase(HttpServletResponse)引发异常{
回复:setStatus(503,“自定义”);
}
}

您在问题中没有这样说,但我猜您正在使用Tomcat。默认情况下,Tomcat只发送状态代码,不发送原因短语。原因短语是HTTP规范的可选部分,因此我不建议依赖它来发送

如果您确实希望依赖自定义原因短语,而不是像其他答案所建议的那样使用响应正文,那么您必须配置Tomcat以发送原因短语(只有Tomcat 8.5支持的内容),或者切换到另一个容器。对于SpringBoot支持的嵌入式servlet容器,Jetty和Undertow都会发送原因短语

下面是一个小示例,它将Tomcat配置为发送原因短语并启用cust的使用