skip to Main Content

I am working on a Java Spring Boot application. I have a JSON in the following format. I need to search for a string and return the results in the same JSON format containing only the matching entries.

The original JSON is:

{
    "version": "1.0.2",
    "students": ["John Smith", "John Green", "Martin King"],
    "teachers": ["John Lord", "Martin Evans", "Steve John", "Gordon Lee", "Leo Martin"],
    "authors" : ["Martin Fowler", "Erich Gamma"]
}

For example, if I search for the string "mart", it should return the JSON below:

{
    "version": "1.0.2",
    "students": ["Martin King"],
    "teachers": ["Martin Evans", "Leo Martin"],
    "authors" : ["Martin Fowler"]
}

How can I do this efficiently? Thank you.

2

Answers


  1. We can use java HashMaps for this. here is an example of how you can do this in spring.

    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    @RestController
    public class SearchController {
    
        private final String jsonData = "{n" +
                "    "version": "1.0.2",n" +
                "    "students": ["John Smith", "John Green", "Martin King"],n" +
                "    "teachers": ["John Lord", "Martin Evans", "Steve John", "Gordon Lee", "Leo Martin"],n" +
                "    "authors" : ["Martin Fowler", "Erich Gamma"]n" +
                "}";
    
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        @GetMapping("/search")
        public Map<String, Object> search(@RequestParam String keyword) {
            try {
                Map<String, Object> data = objectMapper.readValue(jsonData, HashMap.class);
                Map<String, Object> filteredData = new HashMap<>();
                filteredData.put("version", data.get("version"));
                filteredData.put("students", filterList((List<String>) data.get("students"), keyword));
                filteredData.put("teachers", filterList((List<String>) data.get("teachers"), keyword));
                filteredData.put("authors", filterList((List<String>) data.get("authors"), keyword));
    
                return filteredData;
            } catch (Exception e) {
                e.printStackTrace();
                return new HashMap<>();
            }
        }
    
        private List<String> filterList(List<String> list, String keyword) {
            return list.stream()
                    .filter(item -> item.toLowerCase().contains(keyword.toLowerCase()))
                    .collect(Collectors.toList());
        }
    }
    

    and after sending a request to the endpoint with the keyword mart this is the output

    {
        "version": "1.0.2",
        "students": ["Martin King"],
        "teachers": ["Martin Evans", "Leo Martin"],
        "authors": ["Martin Fowler"]
    }
    
    Login or Signup to reply.
  2. You can create a record/POJO called Result that syncs up with the JSON data, and filter on the fields.

    Here is an immutable/functional approach:

    import java.util.*;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class FilterJSON {
        public record Result(String version, List<String> students, List<String> teachers, List<String> authors) {}
    
        private static final ObjectMapper objectMapper = new ObjectMapper();
    
        public static void main(String[] args) throws JsonProcessingException {
            String data = """
                    {
                        "version": "1.0.2",
                        "students": ["John Smith", "John Green", "Martin King"],
                        "teachers": ["John Lord", "Martin Evans", "Steve John", "Gordon Lee", "Leo Martin"],
                        "authors" : ["Martin Fowler", "Erich Gamma"]
                    }
                    """;
    
            Result result = objectMapper.readValue(data, Result.class);
            Result filtered = filter(result, "mart");
            System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(filtered));
        }
    
        public static Result filter(Result result, String term) {
            String criteria = term.toLowerCase();
            List<String> students = filterList(result.students(), criteria);
            List<String> teachers = filterList(result.teachers(), criteria);
            List<String> authors = filterList(result.authors(), criteria);
            return new Result(result.version(), students, teachers, authors);
        }
    
        private static List<String> filterList(List<String> list, String term) {
            return list.stream()
                    .filter(name -> Optional.ofNullable(name)
                            .map(String::toLowerCase)
                            .orElse("")
                            .contains(term))
                    .toList();
        }
    }
    

    Result

    {
      "version" : "1.0.2",
      "students" : [ "Martin King" ],
      "teachers" : [ "Martin Evans", "Leo Martin" ],
      "authors" : [ "Martin Fowler" ]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search