简体   繁体   中英

How to constantly patch a complex one-to-many JsonObject in springboot

Can please anyone guide me, there is 3 level related data that needs to be patched in a interval. The mock code is below:

Collections:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "clients")
public class SavedClient {
  @MongoId
  private String clientId;
  @DocumentReference
  @JsonProperty("clientDate")
  private List<ClientDate> clientDate;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "dates")
public class ClientDate {
    @MongoId
    private String savedDate;
    @DocumentReference
    @JsonProperty("clientLocation")
    private List<ClientLocation> clientLocation;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "times")
public class ClientLocation {
    @MongoId
    private String savedTime;
    private Double longitude;
    private Double latitude;
    private Double altitude;
}

Using CommandLineRunner, it creates all the collections and relations required

@Bean
CommandLineRunner runner(MongoTemplate template) {
    return args -> {
        ClientLocation clientLocation1 = 
                new ClientLocation(localDateTime.format(timeFormatter), 
                        48.45001, 28.8001, 5.1);
        ClientLocation clientLocation2 = 
                new ClientLocation(localDateTime.plusSeconds(3).format(timeFormatter), 
                        48.45002, 28.8002, 5.2);
        ClientLocation clientLocation3 = 
                new ClientLocation(localDateTime.plusSeconds(6).format(timeFormatter), 
                        48.45003, 28.8003, 5.3);
        ClientLocation clientLocation4 = 
                new ClientLocation(localDateTime.plusSeconds(9).format(timeFormatter), 
                        48.45004, 28.8004, 5.4);
        

    template.insert(clientLocation1);
    template.insert(clientLocation2);
    template.insert(clientLocation3);
    template.insert(clientLocation4);
    
    ClientDate clientDate1 = 
            new ClientDate(localDateTime.format(dateFormatter), 
                    List.of(clientLocation1, clientLocation2));
    ClientDate clientDate2 = 
            new ClientDate(localDateTime.plusDays(1).format(dateFormatter), 
                    List.of(clientLocation3, clientLocation4));
    
    template.insert(clientDate1);
    template.insert(clientDate2);
    
    SavedClient savedClient1 = 
            new SavedClient(UUID.randomUUID().toString(), List.of(clientDate1, clientDate2));
    SavedClient savedClient2 = 
            new SavedClient(UUID.randomUUID().toString(), List.of(clientDate1, clientDate2));

    template.insert(savedClient1);
    template.insert(savedClient2);

};

}

How can I patch/put the client in the controller by posting to the same URL like below:

public void postData(final String clientId, final String longitude, final String latitude, final String altitude) {
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    String url = "http://uuu.rrr.lll:8888/clients"; // <----enter your post url here

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH.mm.ss");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
    LocalDateTime localDateTime = LocalDateTime.now();

    JSONObject clientLocation = new JSONObject();
    JSONObject clientDate = new JSONObject();
    JSONObject savedClient = new JSONObject();

    JSONArray clientLocationArray = new JSONArray();
    JSONArray clientDateArray = new JSONArray();

    try {

        clientLocation.put("savedTime", localDateTime.format(timeFormatter));
        clientLocation.put("longitude", longitude);
        clientLocation.put("latitude", latitude);
        clientLocation.put("altitude", altitude);
        clientLocationArray.put(clientLocation);

        clientDate.put("savedDate", localDateTime.format(dateFormatter));
        clientDate.put("clientLocation", clientLocationArray);
        clientDateArray.put(clientDate);

        savedClient.put("clientId", clientId);
        savedClient.put("clientDate", clientDateArray);

    } catch (JSONException e) {
        e.printStackTrace();
    }

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
            Request.Method.POST, url, savedClient,
            response -> Log.e("onResponse: ", response.toString()),
            error -> Log.e("onErrorResponse: ", error.toString()));

    requestQueue.add(jsonObjectRequest);
}

MAN THAT'S A LOT OF CODE SORRY IF IT'S INCONVENIENT!!!

I managed to write something, that worked some way. On the Android side I ditched the complex JsonObject and simply add all to one:

JSONObject client = new JSONObject();
client.put("clientId", clientId);
client.put("savedDate", localDateTime.format(dateFormatter));
client.put("savedTime", localDateTime.format(timeFormatter));
client.put("longitude", longitude);
client.put("latitude", latitude);
client.put("altitude", altitude);

Changed the JsonObjectRequest's method to PUT. On the other side I created a class that takes all the data as fields and passed it throw layers:

Controller.

@PutMapping("/clients")
public SavedClient receiveMockClient(@RequestBody MockClient mockClient) {
    log.info("on insertClient(): method called");
    return service.transmitMockClient(mockClient);
}

Service.

@Override
public SavedClient transmitMockClient(MockClient mockClient) {
    boolean dateById = clientDateRepository.existsById(mockClient.getSavedDate());
    boolean clientById = savedClientRepository.existsById(mockClient.getClientId());
    
    SavedClient client;
    ClientDate date = null;
    ClientLocation time = new ClientLocation(mockClient.getSavedTime(), 
                Double.valueOf(mockClient.getLongitude()), 
                Double.valueOf(mockClient.getLatitude()), 
                Double.valueOf(mockClient.getAltitude()));
        mongoTemplate.insert(time, "times");
    
    if(clientById) {
        
        return mongoTemplate.update(SavedClient.class)
                .matching(Criteria.where("clientId").is(mockClient.getClientId()))
                .apply(new Update().addToSet("clientDate", date))
                .findAndModifyValue();
        
    } else {
        
        if(dateById) {
            date = mongoTemplate.update(ClientDate.class)
                    .matching(Criteria.where("savedDate").is(mockClient.getSavedDate()))
                    .apply(new Update().addToSet("clientLocation", time))
                    .findAndModifyValue();
        } else {
            
            List<ClientLocation> locations = new ArrayList<ClientLocation>();
            locations.add(time);
            date = new ClientDate(mockClient.getSavedDate(), locations);
            clientDateRepository.insert(date);
        }
        
        List<ClientDate> dates = new ArrayList<ClientDate>();
        dates.add(date);
        client = new SavedClient(mockClient.getClientId(), dates);
        return mongoTemplate.insert(client);
}

It's all I could think of, if there is a better way I would like to know it. THX

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM