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

XML解析小坑记录[正则表达式解析]

一、问题描述

在做 SSO 单点登录时( 认证中为CAS服务对接 )。在完成对用户ticket票根校验后,返回了用户信息有关 XML 数据片段,例如下:

<cas:serviceResponse xmlns:cas="http://www.xxx.xx/xx/cas">
  <cas:authenticationSuccess>
    <cas:user>200161</cas:user>
    <cas:username>张三</cas:username>
    <cas:usertype>TEACHER</cas:usertype>
  </cas:authenticationSuccess>
</cas:serviceResponse>

获取到CAS 认证中心返回的数据后,通过 Java中的 PatternMatcher 对象来获取XML 中的数据!

Pattern 和 Matcher 是用于处理正则表达式的两个主要类。

它们的主要作用和用途如下:

  1. Pattern 类
  • 作用:Pattern类是用于编译正则表达式的类。它代表一个编译后的正则表达式,可以对输入的字符串执行匹配操作。
  • 创建:通过调用静态方法 Pattern.compile() 来创建 Pattern 对象,并传入需要的正则表达式作为参数。
  1. Matcher 类
  • 作用:Matcher 类是对输入字符串进行匹配和搜索的类。它与 Pattern 对象一起使用,用于执行匹配操作。
  • 创建:通过调用 Pattern 对象的 matcher 方法创建 Matcher 对象,并传入需要匹配的字符串。
// 解析XML数据,获取指定信息
Pattern pt = Pattern.compile("<cas:user>(.*)</cas:user>");
Matcher matcher = pt.matcher(resultXml);
while (matcher.find()){
    group0 = matcher.group(0).trim();
    group1 = matcher.group(1).trim();
}

​ 上面通过 Pattern 和 **Matcher **来解析出用户信息,但是使用到了 matcher.group(0) 获取的用户信息! 导致后续操作(我的后续操作是拿到的用户信息进行特定的加密后封装一个重定向路径)中使用获取到的用户信息一直失败,也没找到原因!!

  • 后面找到问题所在:使用 group(n) 方法获取匹配的内容:group(0) 返回整个匹配的部分,group(1) 返回第一个括号内的内容 !

这里至于为什么没有发现 通过 matcher.group(0) 和 matcher.group(1) 获取到的值不一样! 是因为我将这两值都直接返回到视图中渲染了,但在视图中展示的内容 他们是一样的!!

二、复现坑

controller 层代码:

package com.example.gsxy_sso_u8cloud.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName : XmlBugController
 * @Description : 测试解析XML文件时出现的坑!
 * @Author : AD
 */

@RestController
@RequestMapping("/xmlbug")
public class XmlBugController {

    /**
     * Description: 模拟解析XML文件的接口
     *  通过 group(0) / group(1)  对比从XML数据中提取的值!
     *
     * @param
     * @return java.lang.String
     * @date 2024-10-24
    */
    @GetMapping("/getXmlInfo")
    public String getXmlInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {


        // 模拟Cas认证校验成功后,返回的用户信息数据 resultXml
        String resultXml = "<cas:serviceResponse xmlns:cas=\"http://www.xxx.xxx/xx/cas\"> "+
                            " <cas:authenticationSuccess> "+
                            " <cas:user>200161</cas:user> "+
                            " <cas:username>张三</cas:username> "+
                            " <cas:usertype>TEACHER</cas:usertype> "+
                           " </cas:authenticationSuccess> "+
                         " </cas:serviceResponse> ";

        /**
         * 定于两个接收解析数据的对象 分别接收 group(0) 和 group(1)
         * */
        String group0 = "";
        String group1 = "";

        // 解析XML数据,获取指定信息
        Pattern pt = Pattern.compile("<cas:user>(.*)</cas:user>");
        Matcher matcher = pt.matcher(resultXml);
        while (matcher.find()){
            group0 = matcher.group(0).trim();
            group1 = matcher.group(1).trim();
        }
        System.out.println("从XML中解析出来的 group0 = " + group0);
        System.out.println("从XML中解析出来的 group1 = " + group1);

        /*
        // 设置响应内容类型为 XML
        response.setContentType("application/xml;charset=UTF-8");
        // 创建 XML 内容
        String xmlContent = "<cas:user>200161</cas:user>";
        // 输出 XML 内容
        response.getWriter().write(xmlContent);
        */

        return "group0 = "+ group0+" \t\n"+
                "group1 = "+ group1+" \t\n";
    }
}

访问controller 接口查看响应数据:

可以看出在浏览器中渲染出来的数据,显式的结果是一样的!!!~~ 所以这里就导致我没发现端倪( 因为远程服务器的配置特殊 )!!!

但是我们可以通过 页面元素 和 网络响应中看出他们的不同之处!

  • 页面元素:

  • 网络响应:

为什么是使用 group(1) 而不是 group(0) 呢?

在使用正则表达式时,group(0) 和 group(1) 的含义是不同的:

  1. group(0):

○ 返回整个匹配的字符串。这是正则表达式匹配结果的完整文本,包括所有的匹配内容。

○ 在你的例子中,group(0) 将返回整个匹配的内容,例如:“cas:user200161</cas:user>”。

  1. group(1):

○ 返回第一个捕获组中的内容。当你在正则表达式中使用括号 () 来创建捕获组时,你可以通过 group(1) 访问第一个捕获组所匹配的内容。

○ 在你的例子中,group(1) 将返回被 cas:user 标签包围的内容,即实际的用户 ID,例如 “200161”。


http://www.kler.cn/news/365088.html

相关文章:

  • Servlet(三)-------Cookie和session
  • 雷池社区版有多个防护站点监听在同一个端口上,匹配顺序是怎么样的
  • (一)Mysql篇---Mysql整体架构
  • 云计算行业应用实训室建设方案
  • Failed to fetch dynamically imported module
  • 合约门合同全生命周期管理系统:企业合同管理的数字化转型之道
  • 学习莫烦python---神经网络
  • 重生之“我打数据结构,真的假的?”--3.栈和队列(无习题)
  • PyTorch 介绍
  • Unity Apple Vision Pro 自定义手势识别交互
  • Vuex 状态机
  • Http模块总体设计
  • C# SM2 加签、验签工具
  • 【SpringCloud】Seata微服务事务
  • 【Flutter】路由与导航:基础路由与导航
  • HTML5教程(一)- 网页与开发工具
  • 基于RK3588/算能BM1684 AI盒子:综合视频智能AI分析系统建设方案(三)安全帽、睡岗检测、电瓶车、吸烟场景
  • 51单片机——OLED显示图片
  • Python进阶知识3
  • 数字 图像处理算法的形式
  • 第二单元历年真题整理
  • vivado 接口带宽验证
  • 第五十四章 安全元素的详细信息 - DerivedKeyToken 详情
  • essay
  • 滤波算法与SLAM:从概率角度理解SLAM问题
  • 如何快速生成大量有意义的测试数据?