状态码如何返回Http/1.1 200 OK

近日,在与某平台调试的时候,发觉对方在一直发送,而我方按照他们文档的格式要求返回的数据,对方还是未能结束一直发送。

后经查证,对方要求我方返回状态码为Http/1.1 200 OK, 而我方返回的数据为Http/1.1 200;

经查证,我方使用的spring-boot-starter-tomcat:2.3.3.Release(tomcat版本为9.0.37),这个版本里面tomcat发行方已将OK这个描述去掉。

网上查找解决方案,多为建议降低Tomcat版本号,不使用SpingBoot自带的Tomcat而直接使用tomcat,然后利用TomcatConfig的方式来进行操作。我看到所有的设置里面,都用到了如下描述:

打开tomcat目录下的server.xml,在<Connector>标签中添加sendReasonPhrase="true"即可
参考链接:https://blog.csdn.net/qq_22937623/article/details/82998899

那么很显然,这个 sendReasonPhrase属性是Tomcat自带的,严格来说是无需干掉SpringBoot内嵌Tomcat的,直接在里面配置也行。

首先,在这个网址上Maven仓库上去查找最接近8点几的 Spring Boot Starter Tomcat 2.x,经查找,最低的版本为2.1.0.RELEASE那么降低SpringBoot版本为2.1.0.RELEASE,内嵌Tomcat就变成了9.0.12就那么更改,最后得到的结果如下:

1、在代码中做如下配置:

package net.dlet.dhdemo.configure;

import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description: 
 * 1、配置转义字符, 解决当请求路径中特殊字符,解决高版本Tomcat对接口参数限制字符,
 * 解析失败从而出现RFC7230、RFC3986问题
 * 2、解决Header状态码加上描述字段的问题
 * @PackageName: net.dlet.dhdemo.configure
 * @Name: RF7230
 * @Author: cure
 * @CreateDate: 2020/09/06 00:30
 * @ModifyUser: cure
 * @ModifyDate: 2020/09/09 22:18
 * @ModifyDesc: 新增解决Header状态码加上描述字段的问题
 * @DayNameFull: 星期日
 * @ProjectName: dhdemo
 * @Version: 1.0
 **/
@Configuration
public class RFC7230 {

    /**
     * 解决Tomcat RFC7230以及Header状态码加上描述字段的问题
     *
     * @return
     */
    @Bean
    public ServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
            //设置解析描述符为true,例如Header 状态码为200,那么解析出来就是200 ok
            connector.setProperty("sendReasonPhrase", "true");
            //以下设置为解决RFC7230问题
            connector.setProperty("relaxedQueryChars", "|{}[](),/:;<=>?@[\\]{}\\");
            connector.setProperty("relaxedPathChars", "|{}[](),/:;<=>?@[\\]{}\\");
            //这个属性在tomcat为8.5的时候不生效
            connector.setProperty("rejectIllegalHeader", "false");
        });

        return factory;
    }

}

2、如何查看这个Tomcat的版本支持 sendReasonPhrase这个属性呢?不想查找文档的话,一个比较笨的方式就是打断点,查看返回值,如下:

 3、pom.xml里面也要修改:

如果是gradle的工程,如下修改:

gradle.properties里面定义版本如下:

spring_boot_version = 2.1.1.RELEASE
spring_boot_tomcat_version = 2.3.3.RELEASE
tomcat_embed_version = 8.5.56

在build.gradle里面修改如下:

       compile("org.springframework.boot:spring-boot-starter-web:${spring_boot_version}") {
            //移除默认的版本
            exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-core:9.0.13'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-el:9.0.13'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.13'
        }

        compile("org.springframework.boot:spring-boot-starter-websocket:${spring_boot_version}") {
            //移除默认的版本
            exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-core:9.0.13'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-el:9.0.13'
            exclude module: 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.13'
        }

        //使用指定版本的tomcat内嵌版本
        compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: "${tomcat_embed_version}"
        compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-el', version:  "${tomcat_embed_version}"
        compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-websocket', version:  "${tomcat_embed_version}"

4、最终返回结果如下:

 

写在最后,吐槽一下:

厂商所用版本实在是太老,文档里面又没有说明他们所测试过的环境,真的十分坑,写tmd个对外文档,根本不像是一个大厂出品,建议这家写技术文档的人,参考一下我6年前写的这篇《Qt5.2.1 交叉编译,带tslib插件》的格式。在开始阶段我就指明了所用环境。

 

第二:吐槽一下百度,等我折腾完了以后,回过去按照现有的关键字(

connector.setProperty("sendReasonPhrase", "true");

)查找,竟然发觉已有人采用了我同样的方式处理问题。然后我将SpringBoot的版本号改为了2.1.5

 

 

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个使用 Java 和 Vue.js 实现 HTTP/1.1 长连接的前后端示例: 后端(Java + Spring Boot): ```java @RestController public class DataController { // 注入 SimpMessagingTemplate 对象 @Autowired private SimpMessagingTemplate messagingTemplate; // 处理 GET 请求,指定 URL 为 /api/data @GetMapping("/api/data") public void getData() { // 设置 HTTP 头部,指定响应的数据类型 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 创建响应对象 ResponseEntity<String> response = new ResponseEntity<>("{\"message\":\"Hello, World!\"}", headers, HttpStatus.OK); // 发送响应数据 messagingTemplate.convertAndSend("/topic/data", response); } } ``` 在这个示例中,后端使用 Spring Boot 框架创建了一个 GET 请求的处理器,当请求的 URL 为 /api/data 时会返回一个 JSON 格式的响应数据。由于 HTTP/1.1 支持长连接,因此在发送响应数据时,将使用 SimpMessagingTemplate 对象将响应数据发送到 WebSocket 的主题 /topic/data 中,以便前端能够接收到数据。 前端(Vue.js): ```vue <template> <div> <h1>{{ message }}</h1> </div> </template> <script> export default { data() { return { message: '' }; }, mounted() { // 创建一个 WebSocket 连接 const ws = new WebSocket('ws://localhost:8080/ws'); // 监听 WebSocket 连接的打开事件 ws.onopen = () => { // 发送一个空消息,以启动 HTTP/1.1 长连接 ws.send(''); }; // 监听 WebSocket 连接的消息事件 ws.onmessage = (event) => { // 处理消息数据 const response = JSON.parse(event.data); if (response.status === 200) { this.message = response.data.message; // 继续发送空消息,以保持 HTTP/1.1 长连接 ws.send(''); } }; } }; </script> ``` 在这个示例中,前端使用 Vue.js 框架创建了一个组件,当组件被挂载到 DOM 树上后会创建一个 WebSocket 连接,并向后端发送一个空消息,以启动 HTTP/1.1 长连接。后端会将响应数据发送到 WebSocket 的主题 /topic/data 中,前端会监听该主题的消息事件,并在接收到消息数据后处理数据并向后端发送一个空消息,以保持 HTTP/1.1 长连接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值