修改经过Spring Gateway的表单中的Json数据

这篇具有很好参考价值的文章主要介绍了修改经过Spring Gateway的表单中的Json数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

使用Spring Cloud Gateway作为网关时有时候一个请求是既包含excel又包含json的表单数据,出于各种层面考虑网关需要获取并更新其中的json数据

依赖

  • Spring Boot版本:2.7.15
  • Hutool: 5.8.21
  • Java: 11

实现逻辑

实现分为2个部分

  1. 使用上文提到的ModifyRequestBodyGatewayFilterFactory类来修改请求体,这样最后就不用我们手动包装
  2. 核心service通过将表单转为String,然后根据其中的boundary进行分割,提取修改json报文部分后再进行组装

注意:示例代码的核心service处理的表单内容只是2个,Json数据的key指定为json,另一个excel文件流

自定义filter

@Component
@Slf4j
public class RequestModifyFilter implements GlobalFilter, Ordered {
    @Autowired
    private ModifyRequestBodyGatewayFilterFactory modifyRequestBodyFilter;
    @Autowired
    private JsonRequestBodyRewriteService jsonRequestBodyRewriteService;
    @Autowired
    private FormDataRequestBodyRewriteService formDataRequestBodyRewriteService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
        if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
            // 纯json报文处理逻辑
            return modifyRequestBodyFilter
                    .apply(
                            new ModifyRequestBodyGatewayFilterFactory.Config()
                                    .setRewriteFunction(byte[].class, byte[].class, jsonRequestBodyRewriteService))
                    .filter(exchange, chain);
        } else if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(mediaType)) {
            // form表单数据处理
            return modifyRequestBodyFilter
                    .apply(
                            new ModifyRequestBodyGatewayFilterFactory.Config()
                                    .setRewriteFunction(byte[].class, byte[].class, formDataRequestBodyRewriteService))
                    .filter(exchange, chain);
        } else {
            return filter(exchange, chain);
        }

    }

    @Override
    public int getOrder() {
        return OrderConstant.REQUEST_MODIFY_FILTER.getOrder();
    }
}

核心service

@Service
@Slf4j
public class FormDataRequestBodyRewriteService implements RewriteFunction<byte[], byte[]> {
    private final String BOUNDARY_PREFIX_IN_CONTENT_TYPE = "----WebKitFormBoundary";
    private final String BOUNDARY_PREFIX_IN_FORM_DATA = "------WebKitFormBoundary";
    private final String BOUNDARY_SUFFIX = "--\r\n";

    @Override
    public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] body) {
        String finalResultString = "";

        // 将表单转为字符串格式从而根据boundary分割表单数据。注意这里不能用默认编码
        String request = StrUtil.str(body, StandardCharsets.ISO_8859_1);

        // 获取boundary的随机字符信息
        String contentType = exchange.getRequest().getHeaders().getContentType().toString();
        String randomStr = contentType.substring(contentType.indexOf(BOUNDARY_PREFIX_IN_CONTENT_TYPE) + BOUNDARY_PREFIX_IN_CONTENT_TYPE.length());

        // 这里和前端约定json数据的表单key为json
        String keyPart = "^\r\nContent-Disposition: form-data; name=\"json\"";
        Pattern r = Pattern.compile(keyPart);

        // 根据表单内分割线进行分割。并通过关键段落keyPart来找到目标json数据
        String[] split = request.split(BOUNDARY_PREFIX_IN_FORM_DATA + randomStr);
        for (int x = 0; x < split.length - 1; x++) {
            Matcher m = r.matcher(split[x]);
            if (m.find()) {
                // 找到了json报文部分数据
                String originalJsonString = split[x];

                // 找到 JSON 数据的起始和结束位置
                int startIndex = originalJsonString.indexOf("{\"");
                int endIndex = originalJsonString.indexOf("\"}") + 2;
                // 提取 JSON 数据
                String jsonData = originalJsonString.substring(startIndex, endIndex);
                log.info("原始报文为:{}", jsonData);

                JSONObject jsonObject = JSONUtil.parseObj(jsonData);
                jsonObject.set("empId", "2345");
                jsonObject.set("department", "Engineering");
                String modifiedString = originalJsonString.substring(0, startIndex) + jsonObject + originalJsonString.substring(endIndex);
                log.info("修改后报文为:{}", modifiedString);

                // 重新组装split数组
                finalResultString = finalResultString + modifiedString + BOUNDARY_PREFIX_IN_FORM_DATA + randomStr;
            } else {
                // 重组表单数据
                finalResultString = finalResultString + split[x] + BOUNDARY_PREFIX_IN_FORM_DATA + randomStr;
            }
        }

        // 补上最后一截数据
        finalResultString = finalResultString + BOUNDARY_SUFFIX;

        return Mono.just(finalResultString.getBytes(StandardCharsets.ISO_8859_1));
    }
}

相关代码

https://github.com/eastcukt/demo-gatway

其他

核心service获取表单中的json数据逻辑挺复杂,根本原因是没有合适的方法进行对象转换,如果有像使用@RequestPart(value = "json")注解一样方便的方法将会非常方便也不用自己截取,各位大佬有更方便的方法感谢分享一下

参考

https://blog.csdn.net/qq_36966137/article/details/128536391文章来源地址https://www.toymoban.com/news/detail-712273.html

到了这里,关于修改经过Spring Gateway的表单中的Json数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 鼠标指针经过时背景变色

    目录 一、如何使用鼠标指针经过时背景变色? 二、使用步骤 1.CSS(表格的样式) 2.表格(5行7列的一个表格) 2.Script部分(实现鼠标指针经过时背景变色效果) 总结 提示:以下是本篇文章正文内容,下面案例可供参考 在之前学习css的时候也学过hover的使用也可以进行该操作

    2024年02月12日
    浏览(37)
  • Form Generator 表单JSON数据储存以及JSON回显表单

    form-generator的作者是这样介绍的:Element UI表单设计及代码生成器,可将生成的代码直接运行在基于Element的vue项目中;也可导出JSON表单,使用配套的解析器将JSON解析成真实的表单。 但目前它提供的组件并不能满足我们在项目中的使用。所以该专栏主要讲解如何在该项目中从零

    2024年02月14日
    浏览(29)
  • 修改ECSHOP评论表单中的Email为非必填的修改方法

    ECSHOP的商品详情页,在用户提交评论的时候,那个“E-MAIL”输入框默认是“必填”的,如果我想改成“E-MAIL非必填”或者干脆“删除这个E-MAIL输入框”,要如何修改才能达到效果呢? 下面以ECSHOP 2.7.2 官方默认模板为基础进行讲解说明。 将E-MAIL改成非必填项 将E-MAIL改成非必填

    2023年04月16日
    浏览(24)
  • Spring Boot 中的 Spring Cloud Gateway

    Spring Cloud Gateway 是一个基于 Spring Boot 的网关框架,它提供了一种统一的入口,将所有的请求路由到不同的后端服务中。Spring Cloud Gateway 采用了 Reactive 编程模型,可以处理大量并发请求,同时还具备负载均衡、熔断、限流等功能。本文将介绍 Spring Cloud Gateway 的原理和使用方法

    2024年02月12日
    浏览(36)
  • Vue表单数据修改与删除

    学习来源:视频p6 书接上文 将之前的 BookManage 页面的按钮改为想要的功能 可以注意到修改按钮的标签以及绑定了事件 handleClick 点击之后其可以在控制台打印出当前行对象的内容 观看视频时,关于修改数据,弹幕分为了两派 一派认为因该直接从页面中获取现有的数据信息加

    2024年02月04日
    浏览(25)
  • SpringGateway网关(Spring Gateway是Spring自己编写的,也是SpringCloud中的组件)

    目录 SpringGateway网关 奈非框架简介 什么是网关 网关的主要功能有 Spring Gateway简介 网关路由配置 动态路由 早期(2020年前)奈非提供的微服务组件和框架受到了很多开发者的欢迎 这些框架和SpringCloud Alibaba的对应关系我们要了解 现在还有很多旧项目维护是使用奈非框架完成的微

    2024年02月09日
    浏览(31)
  • 【JAVA WEB】获取/修改 元素属性&&表单元素属性&&样式属性 以及如何操作DOM树中的节点

    目录 获取/修改元素属性 获取/修改表单元素属性 切换按钮的文本 实现计数器 全选/取消全选按钮 获取/修改样式属性 行内样式操作  类名样式操作 操作节点  新增节点 1.创建元素节点 2.插入节点到dom树中 删除节点  可以通过Element对象的属性来直接修改,就能影响到页面显

    2024年02月22日
    浏览(44)
  • 如何修改JSON数组中的每个对象的userType属性值

    要修改JSON数组中的每个对象的`userType`属性值,您可以使用JavaScript的`map`函数或`forEach`循环。 以下是使用`map`函数的示例: ```javascript ``` 在上述示例中,我们使用`map`函数遍历原始数据数组,对于每个对象,我们检查是否存在`userType`属性,然后将其值修改为新值(在这里将其

    2024年02月10日
    浏览(33)
  • 深入理解HTTP请求中常见的数据类型包括表单数据、JSON、XML和文件上传等。

    本文将介绍HTTP请求中常见的数据类型,包括表单数据、JSON、XML和文件上传等。通过详细解释每种数据类型的特点、用途和示例,帮助读者深入理解并正确使用这些常见的HTTP数据类型。 在Web开发中,HTTP是一种常用的通信协议,用于客户端和服务器之间的数据交互。HTTP请求中

    2024年02月10日
    浏览(73)
  • ElementUI的Form表单使用slot-scope=“scope“获取当前表格行数据实现数据回显、修改表单操作

    在写项目时,老师通过向后端发请求获得表格原来的数据来填充修改表单里的数据。 这是表格: 这是点击修改按钮后显示出来的修改表单: 但本地里都已经有这些数据了,就没必要再发一次请求,徒增服务器压力。 准备 可是该怎么获得当前行的数据填充上去呢?答案在

    2023年04月23日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包