Getting values(real value) from dynamic json object according to database records(place holders) and replace placeholders with real value

huangapple go评论77阅读模式
英文:

Getting values(real value) from dynamic json object according to database records(place holders) and replace placeholders with real value

问题

在这段代码中,我需要根据数据库记录从动态 JSON 对象中获取值。我的数据库中有两个表,一个是通知(notification),另一个是占位符(placeholders),它们之间是多对多的关系。通知可以包含动态数量的占位符,并且一个服务将向此服务发送 JSON POST 请求,以便将占位符替换为真实值。但是由于这个服务不知道动态占位符的数量,真实值应该从动态 JSON 数组中获取。JSON 对象包含通知 ID,并且使用通知 ID,我可以获取通知对象和相应的占位符,然后我可以从 JSON 对象中获取真实值。

这是动态 JSON 对象:

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

这是与 messageId 为 9 相关的通知消息:

"You have successfully subscribed to <PACKNAME> and it will be <PACKTYPE> package"

这应该是输出:

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

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

@Service
public class NotificationServiceImpl implements NotificationService {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    NotificationRepository notificationRepository;

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

        // 创建对象映射器实例
        ObjectMapper mapper = new ObjectMapper();

        // 将 JSON 字符串转换为 Java 对象
        DynamicJson dynamicJson1 = mapper.readValue(dynamicJson, DynamicJson.class);

        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());
    }
}

实体类:

public class 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<>();
}

控制器:

@Autowired
NotificationService 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 successfully subscribed to Youtube and it will be <PACKTYPE> package
You have successfully subscribed to <PACKNAME> and it will be Social Media package

我真正需要的是:

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

占位符和真实值元素的数量是动态的,从 1 到 n。

英文:

In this code section I need to get values from dynamic json object according to database record. I've two tables on database called notification and placeholders many to many relationship and notification can contain dynamic number of placeholders and one service will send json post request to this services so that replace places holders with real value but since this service doesn't know about what are the number of dynamic placeholders real value should get from dynamic json array but json object contain notification id and using notification id I can get notification object and corresponding placeholders then I can get the real values from json object.

Here is dynamic json object.

{  
&quot;messageId&quot;:9,
&quot;msisdn&quot;:&quot;94763703355&quot;,
&quot;&lt;PACKNAME&gt;&quot;:&quot;Youtube&quot;,
&quot;&lt;PACKTYPE&gt;&quot;:&quot;Social Media&quot;,
}

Here is a notification message related to messageId : 9

&quot;You have succuessfully subscribe to &lt;PACKNAME&gt; and it will be &lt;PACKTYPE&gt; package&quot;

This should be output :

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

All placeholders should be replaced with relevant values but I'm unable to get expected output

@Service
public class NotificationServiceImpl implements 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&lt;Notification&gt; notification = notificationRepository.findById(id);
List&lt;PlaceHolder&gt; placeHolders = notification.get().getPlaceHolders();
Map&lt;String, String&gt; replacements = new HashMap&lt;String, String&gt;();
placeHolders.forEach(i -&gt; replacements.put(i.getValue(), dynamicJson1.getPlaceholders().get(i).toString()));
String message = notification.get().getMessage();
StringBuilder result = new StringBuilder(message.length());
String delimiters = &quot;+-*/(),. &quot;;
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());
}
}

Entity Class

public class DynamicJson {

@Override
public String toString() {
return &quot;DynamicJson{&quot; +
&quot;messageId=&quot; + messageId +
&quot;, msisdn=&#39;&quot; + msisdn + &#39;\&#39;&#39; +
&quot;, placeholders=&quot; + placeholders +
&#39;}&#39;;
}
public DynamicJson() {
}
public DynamicJson(int messageId, String msisdn, Map&lt;String, Object&gt; 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&lt;String, Object&gt; getPlaceholders() {
return placeholders;
}
@JsonAnySetter
public void setAddress(String key, Object value) {
placeholders.put(key, value);
}
private int messageId;
private String msisdn;
private Map&lt;String, Object&gt; placeholders = new HashMap&lt;&gt;();

}

Controller

@Autowired
NotificationService notificationService;

@RequestMapping(value = &quot;/&quot;, method = RequestMethod.POST,
consumes = &quot;application/json&quot;, produces = &quot;application/json&quot;)
public void getObject(@RequestBody String dynamicJson) throws IOException {
notificationService.getdata(dynamicJson);
}

This is what I get as output

You have succuessfully subscribed to Youtube and it will be &lt;PACKTYPE&gt; package
You have succuessfully subscribed to &lt;PACKNAME&gt; and it will be Social Media package

What I really need is

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

Placeholder and realValue element count is dynamic and 1 to n

答案1

得分: 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 successfully subscribed 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());
}
英文:

It is your outer for loop. You loop over your placeholders. You should put your placeholders in a Map with the value being the realValue. Something like this:

Map&lt;String, String&gt; replacements = new HashMap&lt;String, String&gt;();
placeHolders.forEach(i -&gt; replacements.put(i, dynamicJson1.getPlaceholders().get(i).toString()));
String sentence = &quot;You have succuessfully subscribe to &lt;PACKNAME&gt; and it will be &lt;PACKTYPE&gt; package&quot;;
StringBuilder result = new StringBuilder(sentence.length());
String delimiters = &quot;+-*/(),. &quot;;
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());

Edit:
here is the population of the map without using lambda:

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

答案2

得分: 0

我可以修复问题的方法是将字符串构建器替换代码部分放在for循环之外,并且还使用了HashMap来映射占位符和真实值。

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

    // 创建对象映射器实例
    ObjectMapper mapper = new ObjectMapper();

    // 将JSON字符串转换为Java对象
    DynamicJson dynamicJson1 = mapper.readValue(dynamicJson, DynamicJson.class);

    int id = dynamicJson1.getMessageId();

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

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

    // 更改部分
    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();
        // 更改部分
        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());
}
英文:

I could fix issue what I did is I placed the string builder replacing code section out side the for loop and also use Hashmap to map placeholder and 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&lt;Notification&gt; notification = notificationRepository.findById(id);
List&lt;PlaceHolder&gt; placeHolders = notification.get().getPlaceHolders();
//Changed
HashMap&lt;String, String&gt; hash_map = new HashMap&lt;String, String&gt;();
String message = notification.get().getMessage();
for (int i = 0; i &lt; 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 = &quot;+-*/(),. &quot;;
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());
}
}

huangapple
  • 本文由 发表于 2020年7月22日 01:02:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63019462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定