【问题标题】:Getting values(real value) from dynamic json object according to database records(place holders) and replace placeholders with real value根据数据库记录(占位符)从动态json对象中获取值(真实值)并用真实值替换占位符
【发布时间】:2023-04-04 00:05:02
【问题描述】:

在此代码部分中,我需要根据数据库记录从动态 json 对象中获取值。我在数据库上有两个表,称为通知和占位符多对多关系,通知可以包含动态数量的占位符,一个服务将向该服务发送 json 发布请求,以便用实际价值替换占位符,但由于该服务不知道关于动态占位符的数量应该从动态 json 数组中获取实际值,但是 json 对象包含通知 id,使用通知 id 我可以获取通知对象和相应的占位符,然后我可以从 json 对象中获取真实值。

这里是动态 json 对象。

{  
    "messageId":9,
    "msisdn":"94763703355",
    "<PACKNAME>":"Youtube",
    "<PACKTYPE>":"Social Media",
   
}

这里是一条与 messageId 相关的通知消息:9

"You have succuessfully subscribe to <PACKNAME> and it will be <PACKTYPE> package"

这应该是输出:

"You have succuessfully subscribed to Youtube and it will be Social
Media package"

所有占位符都应替换为相关值,但我无法获得预期的输出

@服务 公共类 NotificationServiceImpl 实现 NotificationService{

@Autowired
RestTemplate restTemplate;

@Autowired
NotificationRepository notificationRepository;

@Override
public void getdata(String dynamicJson) throws IOException {


    // create object mapper instance
    ObjectMapper mapper = new ObjectMapper();


    // convert JSON string to Java Object
    DynamicJson dynamicJson1 = mapper.readValue(dynamicJson, DynamicJson.class);

    // print user object
    //System.out.println(dynamicJson1);
    int id = dynamicJson1.getMessageId();

    Optional<Notification> notification = notificationRepository.findById(id);

    List<PlaceHolder> placeHolders = notification.get().getPlaceHolders();


    Map<String, String> replacements = new HashMap<String, String>();
    placeHolders.forEach(i -> replacements.put(i.getValue(), dynamicJson1.getPlaceholders().get(i).toString()));

   String message = notification.get().getMessage();

    StringBuilder result = new StringBuilder(message.length());
    String delimiters = "+-*/(),. ";
    StringTokenizer st = new StringTokenizer(message, delimiters, true);
    while (st.hasMoreTokens()) {
        String w = st.nextToken();
        if (replacements.containsKey(w)) {
            result.append(replacements.get(w));
        } else {
            result.append(w);
        }
    }
    System.out.println(result.toString());


}
}

实体类

公共类 DynamicJson {

@Override
public String toString() {
    return "DynamicJson{" +
            "messageId=" + messageId +
            ", msisdn='" + msisdn + '\'' +
            ", placeholders=" + placeholders +
            '}';
}

public DynamicJson() {

}

public DynamicJson(int messageId, String msisdn, Map<String, Object> placeholders) {
    this.messageId = messageId;
    this.msisdn = msisdn;
    this.placeholders = placeholders;
}

public int getMessageId() {
    return messageId;
}

public void setMessageId(int messageId) {
    this.messageId = messageId;
}

public String getMsisdn() {
    return msisdn;
}

public void setMsisdn(String msisdn) {
    this.msisdn = msisdn;
}

public Map<String, Object> getPlaceholders() {
    return placeholders;
}

@JsonAnySetter
public void setAddress(String key, Object value) {
    placeholders.put(key, value);
}

private int messageId;
private String msisdn;
private Map<String, Object> placeholders = new HashMap<>();

}

控制器

@自动连线 NotificationService 通知服务;

@RequestMapping(value = "/", method = RequestMethod.POST,
        consumes = "application/json", produces = "application/json")
public void getObject(@RequestBody String dynamicJson) throws IOException {

    notificationService.getdata(dynamicJson);

}

这是我得到的输出

You have succuessfully subscribed to Youtube and it will be <PACKTYPE> package

You have succuessfully subscribed to <PACKNAME> and it will be Social Media package

我真正需要的是

You have succuessfully subscribed to Youtube and it will be Social Media package

Placeholder 和 realValue 元素计数是动态的,从 1 到 n

【问题讨论】:

  • 你试过用调试器单步调试代码吗?
  • 是的,但我无法弄清楚出了什么问题
  • 这是你的外层 for 循环。你循环你的占位符。您应该将占位符放在 Map 中,其值为 realValue

标签: java json string spring-boot replace


【解决方案1】:

我可以解决的问题是我将字符串生成器替换代码部分放在 for 循环之外,还使用 ​​Hashmap 映射占位符和 realValue。

 @Override
    public void getdata(String dynamicJson) throws IOException {


        // create object mapper instance
        ObjectMapper mapper = new ObjectMapper();


        // convert JSON string to Java Object
        DynamicJson dynamicJson1 = mapper.readValue(dynamicJson, DynamicJson.class);


        int id = dynamicJson1.getMessageId();


        Optional<Notification> notification = notificationRepository.findById(id);

        List<PlaceHolder> placeHolders = notification.get().getPlaceHolders();

        //Changed
        HashMap<String, String> hash_map = new HashMap<String, String>();


        String message = notification.get().getMessage();


        for (int i = 0; i < placeHolders.size(); i++) {


            String placeholder = placeHolders.get(i).getValue();
            String realValue = dynamicJson1.getPlaceholders().get(placeholder).toString();

            //Changed
            hash_map.put(placeholder, realValue);

        }

        //////////////////////////////////////////////////////////////////////////////////

        StringBuilder result = new StringBuilder(message.length());
        String delimiters = "+-*/(),. ";
        StringTokenizer st = new StringTokenizer(message, delimiters, true);
        while (st.hasMoreTokens()) {
            String w = st.nextToken();
            if (hash_map.containsKey(w)) {
                result.append(hash_map.get(w));
            } else {
                result.append(w);
            }
        }


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

}

【讨论】:

    【解决方案2】:

    这是你的外部 for 循环。你循环你的占位符。您应该将占位符放在 Map 中,其值为 realValue。像这样的:

    Map<String, String> replacements = new HashMap<String, String>();
    placeHolders.forEach(i -> replacements.put(i, dynamicJson1.getPlaceholders().get(i).toString()));
                
    String sentence = "You have succuessfully subscribe to <PACKNAME> and it will be <PACKTYPE> package";
                
    StringBuilder result = new StringBuilder(sentence.length());
    String delimiters = "+-*/(),. ";
    StringTokenizer st = new StringTokenizer(sentence, delimiters, true);
    while (st.hasMoreTokens()) {
       String w = st.nextToken();
       if (replacements.containsKey(w)) {
          result.append(replacements.get(w));
       } else {
          result.append(w);
       }
    }
    System.out.println(result.toString());
    

    编辑: 这是不使用 lambda 的地图人口:

    for(String placeHolder: placeHolders) {
        replacements.put(placeHolder, dynamicJson1.getPlaceholders().get(placeHolder).toString()))
    }
    

    【讨论】:

    • 我直接替换了你的核心,因为我对 lamda 没有太多经验,它询问了所需的类型字符串,但提供的类型是占位符 replaces.put(i, 然后添加 i.getValue() 但得到了一个异常
    • @HashanR,你遇到了什么异常?
    • "trace": "java.lang.NullPointerException\r\n\tat com.hashanr.notificationsender.service.NotificationServiceImpl.lambda$getdata$0(NotificationServiceImpl.java:66)\r\n\ tat java.lang.Iterable.forEach(Ite​​rable.java:75)\r\n\tat com.hashanr.notificationsender.service.NotificationServiceImpl.getdata(NotificationServiceImpl.java:66)\r\n\tat com.hashanr.notificationsender .controller.NotificationController.getObject(NotificationController.java:28)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) \r\n\
    • 我将添加完整的代码,以便您可以清楚地了解。无论如何,我是 Spring Boot 和 Java 的新手
    • @HashanR,你能检查你的 dynamicJson1 对象以确保它有正确的数据吗?
    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2013-08-11
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多