【问题标题】:how to substring a string containing multiple strings如何对包含多个字符串的字符串进行子串化
【发布时间】:2021-09-30 23:55:20
【问题描述】:

我有一个包含多个字符串的字符串对象。我想提取 "_json": 之后的部分,直到它到达 } 但是当我在我的代码中给出这个时,它告诉 index out of bound 异常。 任何人都可以帮助提取那部分 我得到的字符串是

===Username===>>{"profile":{"id":"xxxxxx","name":{},"_raw":"{\"sub\":\"xxxxx\",\"country\":\"US\",\"firstname\":\"xxxx\",\"employeetype\":\"XXXX\",\"mail\":\"abc@yz.com\",\"gehrbusinesssegment\":\"avav\",\"gessobusinessunit\":\"AVI DT-xxxxx Engineering\",\"gessouid\":\"C2B0A5EB-8A20-170F-BF3E-002128B20D70\",\"cn\":\"Saha, Romit\",\"title\":\"Project Manager  (Backend)\",\"georaclehrid\":\"xxxxx\",\"lastname\":\"Saha\",\"uid\":\"xxxxx\",\"groupNAME\":[\"@GE AWS_bu-readonly_175070699551\",\"@GE AWS_bu-readonly_639624358806\",\"@AVIATION MRO Fulfillment Operations Advisor\",\"@POWER pge_role_super_user_dev\",\"@AVIATION DISE Friends of the Family\",\"@AVIATION MOA Users - Editor Access\",\"@AVIATION MOA-Viewer-Users\",\"@Gas Power Smartshop Users\",\"@AVIATION US VPN GROUP\",\"@Digital Emergency Change Notification 23\"],\"gessocompanyname\":\"XXXXXX\",\"gehrindustrygroup\":\"XXXXXX\",\"gessojobfunction\":\"Information Technology\",\"street\":\"XXXXXPlaza\",\"location\":\"XXXX\",\"state\":\"XXX\",\"geECIndicator\":\"N\"}\r\n","_json":{"sub":"XXXX","country":"US","firstname":"Romit","employeetype":"XXX","mail":"XXX@ge.com","gehrbusinesssegment":"XXX","gessobusinessunit":"AVI DT-Data Infrastructure & Software Engineering","gessouid":"C2B0A5EB-8A20-170F-BF3E-002128B20D70","cn":"Saha, Romit","title":"XXXXXX(Backend)","georaclehrid":"XXXX","lastname":"Saha","uid":"502622018","groupNAME":["@GE AWS_bu-readonly_175070699551","@GE AWS_bu-readonly_639624358806","@AVIATION MRO Fulfillment Operations Advisor","@POWER pge_role_super_user_dev","@AVIATION DISE Friends of the Family","@AVIATION MOA Users - Editor Access","@AVIATION MOA-Viewer-Users","@Gas Power Smartshop Users","@AVIATION US VPN GROUP","@Digital Emergency Change Notification 23"],"gessocompanyname":"XXXXX","gehrindustrygroup":"GE Aviation","gessojobfunction":"Information Technology","street":"XXXXX Plaza","location":"XXXX","state":"XXX","geECIndicator":"N"}},"accessTokenExp":1627090679000,"accessToken":"XXXXX","refreshTokenExp":1627105079000,"refreshToken":"XXXXX","user_info":{"family_name":"Saha","given_name":"Romit","user_name":"XXXXX"}}

但是当我在我的代码中给出这个时,它给出了异常

String json = username.substring(username.indexOf("_json") + 1, username.indexOf('}'));

错误:

2021-07-23 20:37:42 [http-nio-9090-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet].log - Servlet.service() for servlet [dispatcherServlet] in context with path [/moa/api/v1] threw exception
java.lang.StringIndexOutOfBoundsException: String index out of range: -1137
        at java.lang.String.substring(String.java:1967) ~[na:1.8.0_251]
        at com.ge.digital.oa.common.config.cloud.oidc.OIDCRequestFilter.doFilterInternal(OIDCRequestFilter.java:80) ~[main/:na]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.17.jar:9.0.17]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]

【问题讨论】:

  • 使用 JSON 解析器。

标签: java json string java-8


【解决方案1】:

由于输入字符串有多个},子字符串的被索引和结束索引超出范围

您当前的开始索引:1189 结束索引53 导致StringIndexOutOfBoundsException:

username.indexOf("}") 更改为username.lastIndexOf("}")

你可以尝试获取'}'的lastIndex

         int begin = username.indexOf("_json") +1;
         int end = username.lastIndexOf("}");
         System.out.println("begin:"+begin+" end:"+end );
         String json = username.substring(begin, end);
         System.out.println(" jsonString: "+json);

输出:

jsonString: json":{"sub":"502622018","country":"US","firstname":"Romit","employeetype":"Contractor","mail":"romit.saha@ge.com","gehrbusinesssegment":"Aviation Digital Technology","gessobusinessunit":"AVI DT-Data Infrastructure & Software Engineering","gessouid":"C2B0A5EB-8A20-170F-BF3E-002128B20D70","cn":"Saha, Romit","title":"Predix Senior Engineer (Backend)","georaclehrid":"502622018","lastname":"Saha","uid":"502622018","groupNAME":["@GE AWS_bu-readonly_175070699551","@GE AWS_bu-readonly_639624358806","@AVIATION MRO Fulfillment Operations Advisor","@POWER pge_role_super_user_dev","@AVIATION DISE Friends of the Family","@AVIATION MOA Users - Editor Access","@AVIATION MOA-Viewer-Users","@Gas Power Smartshop Users","@AVIATION US VPN GROUP","@Digital Emergency Change Notification 23"],"gessocompanyname":"General Electric Company","gehrindustrygroup":"GE Aviation","gessojobfunction":"Information Technology","street":"3200 Windy Hill Road, The Towers at Wildwood Plaza","location":"Atlanta","state":"GA","geECIndicator":"N"}},"accessTokenExp":1627090679000,"accessToken":"0003Kpc7Av3noCCKZrKpcSgPnRb2","refreshTokenExp":1627105079000,"refreshToken":"v4Qx3JcAd99zmZnd5WgvYJw83KHBUkAbnb9Ogn02jS","user_info":{"family_name":"Saha","given_name":"Romit","user_name":"502622018"}

更新:

我建议使用 ObjectMapper 将 jsonstring 转换为 POJO 并从对象访问值

使用工具将json字符串转换为pojo

将 userName json 字符串传递给下面的代码会将 json 字符串映射到 java 对象Root 您可以访问各个成员的所需数据 这里root.getProfile().get_json() 会得到你_json

ObjectMapper om = new ObjectMapper();
Root root = om.readValue(userName), Root.class);

你的pojo如下

public class Name{
}


public class Json{
    public String sub;
    public String country;
    public String firstname;
    public String employeetype;
    public String mail;
    public String gehrbusinesssegment;
    public String gessobusinessunit;
    public String gessouid;
    public String cn;
    public String title;
    public String georaclehrid;
    public String lastname;
    public String uid;
    public List<String> groupNAME;
    public String gessocompanyname;
    public String gehrindustrygroup;
    public String gessojobfunction;
    public String street;
    public String location;
    public String state;
    public String geECIndicator;
}

public class Profile{
    public String id;
    public Name name;
    public String _raw;
    public Json _json;
}

public class UserInfo{
    public String family_name;
    public String given_name;
    public String user_name;
}

public class Root{
    public Profile profile;
    public long accessTokenExp;
    public String accessToken;
    public long refreshTokenExp;
    public String refreshToken;
    public UserInfo user_info;
}

另一个建议是您可以在发布问题之前屏蔽私人数据

【讨论】:

  • 是的...这是正确的..它会在 }} 之后打印字符串的其余部分..需要找到一些技巧
  • 我可以通过修改上面的代码来实现我的目标 -String jsonmiddle = username.substring(begin, end); String jsonfinal = jsonmiddle.substring(jsonmiddle.indexOf("{"),jsonmiddle.indexOf("}")+1);
【解决方案2】:

您可以像这样使用simple-json 库提取该值:

JSONObject jobj = (JSONObject) parser.parse(yourJsonString); 
    
        String _json= (String) jobj.get("_json"); // Extract the value from your key
    
        System.out.println(_json);

【讨论】:

    【解决方案3】:

    发生这种情况是因为当您说username.indexOf('}') 时,它会占用第一个“}”,它位于用户名字符串中的“_json”索引之前。这给出了StringIndexOutOfBoundsException,因为结束索引(substring 方法的第二个参数)需要在开始索引(substring 方法的第一个参数)之后。

    您需要做的是username.split('_json'),然后在拆分调用结果的后半部分调用username.indexOf('}'),以获取“_json”之后第一个“}”字符的索引。然后你就可以username.substring(username.indexOf("_json") + 1, /*insert the index of the '}' character you found earlier here */)

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      相关资源
      最近更新 更多