2

I have a complex string which I need to split two times by delimiters '&' and '=' respectively. Then I need to set the values in Java POJO class.I need values like 2020-08-11+15%3A11%3A49 to be set for requestTimestamp field in pojo, 0036 in channelResponseCode..... Like this for all fields. Due to for each all values are getting set for one field. Please help. My code as follows:

public static void main(String[] args) {
        
        String strMain = "request_timestamp=2020-08-11+15%3A11%3A49&channel_response_code=0036&channel_response_desc=Payment+is+cancelled.&sub_merchant_list=";
        String arrSplit[] = strMain.split("&");
        // [request_timestamp=2020-08-11+15%3A11%3A49, channel_response_code=0036, channel_response_desc=Payment+is+cancelled.,_4=, user_defined_5=, .....]
        //  System.out.println(Arrays.toString(arrSplit));            
        Payment p = new Payment();
        for (String s : arrSplit) {
            String[] t =s.split("=");
        System.out.println(Arrays.toString(t));
      if(t.length >1) {
      p.setRequest_timestamp(t[1]); 
      }
      else { p.setRequest_timestamp(""); }
     
            System.out.println("Hiii"+p.getRequest_timestamp());
      }
    }
Steve
  • 13
  • 7
  • 1
    This looks like URL encoding. Related question: https://stackoverflow.com/questions/11733500/getting-url-parameter-in-java-and-extract-a-specific-text-from-that-url – Hulk Aug 17 '20 at 11:09

4 Answers4

2

You can use StringTokenizer for that purpose.

       private static final String CHANEL_RESPONSE_CODE = "channel_response_code";
private static final String CHANEL_RESPONSE_DESC = "channel_response_desc";
private static final String REQUEST_TIME_STMP = "request_timestamp";
private static final String MERCHANT_LIST = "sub_merchant_list";

public static void main(String[] args) {

    String strMain = "request_timestamp=2020-08-11+15%3A11%3A49&channel_response_code=0036&channel_response_desc=Payment+is+cancelled.&sub_merchant_list=";


    StringTokenizer tokenizer = new StringTokenizer(strMain, "&");



    while (tokenizer.hasMoreElements()){
           String element = tokenizer.nextElement().toString();
           if(element.contains(CHANEL_RESPONSE_CODE)){
               String chanelReponseCodeValue[] = element.split("=");
               if(chanelReponseCodeValue.length>=2){
                   System.out.println(chanelReponseCodeValue[1]);
               }
              
           }
           if(element.contains(CHANEL_RESPONSE_DESC)){
               String chanelReponseDescValue[] = element.split("=");
               if(chanelReponseDescValue.length>=2) {
                   System.out.println(chanelReponseDescValue[1]);
               }
           }
           if(element.contains(REQUEST_TIME_STMP)){
               String  requestTimeStmp[] = element.split("=");
               if(requestTimeStmp.length>=2){
                   System.out.println(requestTimeStmp[1]);
               }

           }
           if(element.contains(MERCHANT_LIST)){
               String  merchantList[] = element.split("=");
               if(merchantList.length>=2) {
                   System.out.println(merchantList[1]);
               }
           }

    }

}
Nemanja
  • 3,295
  • 11
  • 15
  • But how can I set the values in POJO fields. how can I access? – Steve Aug 17 '20 at 12:22
  • Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: using your code. Using split also same Exception is there – Steve Aug 17 '20 at 14:54
  • remember there are fields like merchant list ,... who dont have value. – Steve Aug 17 '20 at 15:05
  • @Steve I updated answer. Just check the length of array which you get when splitting the string by "=" delimiter.. – Nemanja Aug 17 '20 at 15:21
1

Here is a Java8 with Jackson library way of doing it:

Payment Class:

public class Payment {
    
    // You don't need @JsonProperty annotation if you have param name 
    // "requestTimestamp" in your URL or if you name the attribute here in POJO 
    // as "request_timestamp"

    @JsonProperty("request_timestamp")
    String requestTimestamp;
    
    @JsonProperty("channel_response_code")
    String channelResponseCode;
    
    @JsonProperty("channel_response_desc")
    String channelResponseDesc;
    
    @JsonProperty("sub_merchant_list")
    String subMerchantList;

    // getters and setters
}
public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String strMain = "request_timestamp=2020-08-11+15%3A11%3A49&channel_response_code=0036&channel_response_desc=Payment+is+cancelled.&sub_merchant_list=1";

        Map<String, String> map = 
                Arrays.stream(URLDecoder.decode(strMain, "UTF-8").split("&"))
                .collect(
                        Collectors.toMap(
                                k -> ((String) k).split("=")[0], 
                                v -> ((String) v).split("=")[1]) // watch out for ArrayIndexOutOfBoundException
                       ); 
         
         // using Jackson library: import com.fasterxml.jackson.databind.ObjectMapper;
         ObjectMapper mapper = new ObjectMapper();
         Payment pojo = mapper.convertValue(map, Payment.class);

        System.out.println(pojo.toString());
    }
}

Output:

Payment [requestTimestamp=2020-08-11 15:11:49, channelResponseCode=0036, channelResponseDesc=Payment is cancelled., subMerchantList=1]

Note:

  1. You can explore more about URL decoding here (taken from Homilzio's answer)
  2. You can exlpore ObjectMapper for more fine grained conversion.
adarsh
  • 1,393
  • 1
  • 8
  • 16
0

It seems that you are having issues with encoding, you can try:

 URLEncoder.encode(strMain, StandardCharsets.UTF_8);

beefore.

More info in a similar question here

0

What about something like this?

    class Payment {
        String requestTimestamp;
        String channelResponseCode;
        String channelResponseDesc;
        String subMerchantList;

        public static Payment parsePayment(String input) {
            return new Payment(input);
        }

        private Payment(String input) {
            String arrSplit[] = input.split("&");

            for (int i = 0; i < arrSplit.length; i++) {
                String[] keyValue = arrSplit[i].split("=");
                String key = null;
                if (keyValue.length > 0) {
                    key = keyValue[0];
                }
                String value = null;
                if (keyValue.length > 1) {
                    value = keyValue[1];
                }
                this.setPropertyValue(key, value);
            }
        }

        private void setPropertyValue(String key, String value) {
            System.out.println(String.format("'%s' = '%s'", key, value));

            switch (key) {
                case "request_timestamp":
                    this.requestTimestamp = value;
                    return;

                case "channel_response_code":
                    this.channelResponseCode = value;
                    return;

                case "channel_response_desc":
                    this.channelResponseDesc = value;
                    return;

                case "sub_merchant_list":
                    this.subMerchantList = value;
                    return;

                default:
                    throw new RuntimeException(String.format("Invalid key '%s'", key));
            }
        }

        @Override
        public String toString() {
            return "Payment{" +
                    "requestTimestamp='" + requestTimestamp + '\'' +
                    ", channelResponseCode='" + channelResponseCode + '\'' +
                    ", channelResponseDesc='" + channelResponseDesc + '\'' +
                    ", subMerchantList='" + subMerchantList + '\'' +
                    '}';
        }
    }

    @Test
    void stackOverflow() {
        String strMain = "request_timestamp=2020-08-11+15%3A11%3A49&channel_response_code=0036&channel_response_desc=Payment+is+cancelled.&sub_merchant_list=";
        Payment payment = Payment.parsePayment(strMain);
        System.out.println(payment.toString());
    }

The result:

'request_timestamp' = '2020-08-11+15%3A11%3A49'
'channel_response_code' = '0036'
'channel_response_desc' = 'Payment+is+cancelled.'
'sub_merchant_list' = 'null'
Payment{requestTimestamp='2020-08-11+15%3A11%3A49', channelResponseCode='0036', channelResponseDesc='Payment+is+cancelled.', subMerchantList='null'}
Peter Nagy
  • 86
  • 1
  • 7