当前位置: 首页 > article >正文

CXF WebService SpringBoot 添加拦截器,处理响应报文格式

描述

XFIRE升级CXF框架,但是对接的系统不做调整,这时候就要保证参数报文和响应报文和以前是一致的。但是不同的框架有不同的规则,想要将报文调整的一致,就需要用到拦截器拦截报文,自定义解析处理。
CXF框架本身就是支持配置自定义拦截器的,以下是案例。

响应拦截器案例

package com.xinyuan.model.thirdparty.cxf.interceptor;
import org.apache.cxf.interceptor.AttachmentOutInterceptor;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;

public class NamespacePrefixInterceptor extends AbstractPhaseInterceptor<Message> {

    public NamespacePrefixInterceptor() {
        // 在发送消息之前的阶段进行拦截
        super(Phase.PRE_STREAM);
        // 添加依赖的拦截器
        addAfter(AttachmentOutInterceptor.class.getName());
    }

    @Override
    public void handleMessage(Message message) {
        try {
            // 获取输出流
            OutputStream outputStream = message.getContent(OutputStream.class);
            if (outputStream == null) {
                return;
            }

            // 使用 CachedOutputStream 缓存输出流,以便我们可以读取和修改它
            CachedOutputStream cachedOutputStream = new CachedOutputStream();
            message.setContent(OutputStream.class, cachedOutputStream);

            // 在拦截器处理完毕后,将缓存的输出流写回到原始输出流中
            message.getInterceptorChain().doIntercept(message);

            // 读取缓存的输出流内容
            try (CachedOutputStream cos = cachedOutputStream) {
                String response = new String(cos.getBytes());

                // 在这里对 response 进行处理
                String modifiedResponse = processResponse(response);

                // 将处理后的内容写回到输出流中
                try (OutputStream finalOutputStream = outputStream) {
                    finalOutputStream.write(modifiedResponse.getBytes());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private String processResponse(String response) {
        //在这里写处理报文的逻辑
        return response;
    }

}

  • 在发布接口的代码处,添加拦截器
    在这里插入图片描述

通过dom的方式解析xml,并为满足条件的元素添加属性

	public static void main(String[] args){
        String xml = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                "   <soap:Body>\n" +
                "      <ns1:queryGysxxResponse xmlns:ns1=\"http://iface.xt.service.zzxy.com\" xmlns=\"http://entity.service.zzxy.com\">\n" +
                "         <ns1:out>\n" +
                "            <cz>111</cz>\n" +
                "            <dh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <dzyx xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <frdbmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <gsdz xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <gysbh>gysbh</gysbh>\n" +
                "            <gysmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <khhmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <khhzh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <lxrmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <sj xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <xxdz xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <yzbh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <zzjgdmh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "         </ns1:out>\n" +
                "      </ns1:queryGysxxResponse>\n" +
                "   </soap:Body>\n" +
                "</soap:Envelope>";
        try {
            // 创建DocumentBuilderFactory对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 设置命名空间感知
            factory.setNamespaceAware(true);
            // 创建DocumentBuilder对象
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 解析XML字符串
            Document document = builder.parse(new InputSource(new StringReader(xml)));

            // 获取<ns1:out>元素
            NodeList outNodes = document.getElementsByTagNameNS("http://iface.xt.service.zzxy.com", "out");
            if (outNodes.getLength() > 0) {
                Element outElement = (Element) outNodes.item(0);
                // 获取<ns1:out>元素下的所有子节点
                NodeList childNodes = outElement.getChildNodes();
                for (int i = 0; i < childNodes.getLength(); i++) {
                    Node childNode = childNodes.item(i);
                    if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                        // 修改子节点的命名空间
                        //((Element) childNode).setNamespaceURI("http://entity.service.zzxy.com");
                        ((Element) childNode).setAttribute("a","http://entity.service.zzxy.com");
                    }
                }
            }

            // 输出修改后的XML
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(System.out);
            transformer.transform(source, result);

        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

dom4j的方式解析xml,对满足条件的元素添加命名空间

public static void main(String[] args) throws DocumentException {
        String xml = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                "   <soap:Body>\n" +
                "      <ns1:queryGysxxResponse xmlns:ns1=\"http://iface.xt.service.zzxy.com\" xmlns=\"http://entity.service.zzxy.com\">\n" +
                "         <ns1:out>\n" +
                "            <cz>111</cz>\n" +
                "            <dh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <dzyx xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <frdbmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <gsdz xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <gysbh>gysbh</gysbh>\n" +
                "            <gysmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <khhmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <khhzh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <lxrmc xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <sj xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <xxdz xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <yzbh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "            <zzjgdmh xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>\n" +
                "         </ns1:out>\n" +
                "      </ns1:queryGysxxResponse>\n" +
                "   </soap:Body>\n" +
                "</soap:Envelope>";

        try {
            SAXReader reader = new SAXReader();
            Document document = reader.read(new StringReader(xml));
            Element root = document.getRootElement();
            //printElementNames(root);
            //查找 <ns1:out> 元素
            Element ns1OutElement = root.element("Body").element("queryGysxxResponse").element("out");
            // 打印所有的元素名称
            printElementNames(ns1OutElement);
            setNamespaceForChildElements(ns1OutElement);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    private static void setNamespaceForChildElements(Element element) {
        // 创建目标命名空间
        Namespace targetNamespace = new Namespace("", "http://entity.service.zzxy.com");

        // 遍历当前元素的所有子元素
        for (Object child : element.elements()) {
            if (child instanceof Element) {
                Element childElement = (Element) child;

                // 将子元素的 QName 更新为目标命名空间
                QName newQName = new QName(childElement.getName(), targetNamespace);
                childElement.setQName(newQName);
            }
        }
    }

    private static void printElementNames(Element element) {
        // 打印当前元素的名称
        System.out.println(element.getName());

        // 递归打印子元素的名称
        for (Object child : element.elements()) {
            if (child instanceof Element) {
                printElementNames((Element) child);
            }
        }
}

http://www.kler.cn/a/441705.html

相关文章:

  • python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖
  • 本地 AI 模型“不实用”?
  • C#与AI的共同发展
  • js截取video视频某一帧为图片
  • Day 14 卡玛笔记
  • 68,[8] BUUCTF WEB [RoarCTF 2019]Simple Upload(未写完)
  • React里循环tab列表,并实现点击切换class
  • C语言学习day19:结构体/枚举/共用体/游戏结构体的逆向分析
  • Uniapp安卓端获取手机号码
  • Docker中 localhost 与 0.0.0.0 的区别详解
  • oracle client linux服务器安装教程
  • git SSL certificate problem: unable to get local issuer certificate
  • 只出现一次的数字(字节面试题 最优解)
  • OpenCV 功能函数介绍 (二)
  • awk使用详解
  • 【WPF】RenderTargetBitmap的使用
  • 如何让你的 PHP 应用坚不可摧
  • 【网络安全】掌握 Active Directory 攻防审计实操知识点
  • MaskGCT——开源文本转语音模型,可模仿任何人说话声音
  • 宝塔 搭建HOJ 配置域名 反向代理 开启https访问
  • Android使用PorterDuffXfermode的模式PorterDuff.Mode.SRC_OUT实现橡皮擦,Kotlin(1)
  • Flink-Learning全面探索流式处理的卓越框架
  • 【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)
  • CTFHub-ssrf
  • mysql flink cdc 实时数据抓取
  • 大模型QLoRA微调——基于Qwen2-7B的自动化病历摘要生成系统