在Spring Boot REST API中的对象数组

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

Array of Objects in Spring Boot REST API

问题

[已解决!解决方案在代码中体现]

我正在使用Spring Boot进行项目开发,其中我需要在JSON中使用包含对象组的数组。它应该像这个示例一样:

{
  "Spring20": [
    {
      "CSCXXX": "Machine Learning",
       . . . 
    },
    {
      "CSCXXX": "Computer Vision",
       . . . 
    }
  ],  

  "Fall20": [
    {
      "EEXXX": "Electronics",
       . . . 
    }
  ]
}

我尝试使用一个Map,其中存储了一个字符串用于数组科目名称,以及一个列表来保存所有课程对象。这位于服务类中。

HashMap<String, List<Courses>> courseList = new HashMap<String, List<Courses>>();

[为适应解决方案而修改]

服务类

public void add(Map<String, List<Courses>> course) {
    course.forEach((semester, courses) -> {
        if (courseList.containsKey(semester)) {
            courseList.get(semester).addAll(courses);
        } else {
            courseList.put(semester, courses);
        }
    });  
}
public void edit(String semester, String id, Courses courses) {
    // 获取Map中的课程列表
    List<Courses> updatedCourse = courseList.get(semester);
    // 遍历并找到列表中匹配的对象
    for (int i = 0; i < updatedCourse.size(); i++) {
        if (updatedCourse.get(i).getID().equals(id)) {
            // 找到对象后,在列表中更新其值
            updatedCourse.get(i).setSubject(courses.getSubject());
            // ...
            // 最后,替换Map中的列表
            courseList.replace(semester, updatedCourse);
        }
    }
}

控制器

@RequestMapping(method = RequestMethod.POST, value = "/add")
public void addCourse(@RequestBody Map<String, List<Courses>> course) {
    service.add(course);
}

@RequestMapping(method = RequestMethod.PUT, value = "/edit/{semester}/{id}")
public void editCourse(@PathVariable("semester") String semester, @PathVariable("id") String id, @RequestBody Courses course) {
    service.edit(semester, id, course);
}

在首次添加JSON时,一切都按预期工作,我得到了正确的JSON结构。然而,当添加和编辑值时,情况变得复杂起来。

  1. [已解决] 每当我将单个对象添加到数组中时,它会替换先前在数组中的所有对象。
  2. [已解决] 如果我尝试使用Postman进行编辑,我会得到一些异常。

这些错误的解决方案在下面。我希望这篇帖子能帮助到那些可能遇到相同问题的人!

这是我发布的另一篇使用Map<>与MongoDB的帖子。
https://stackoverflow.com/questions/64558958/crud-operations-on-array-objects-nested-within-an-object-in-mongodb-spring-boot

英文:

[Solved! Solution reflected in code]

I'm working on a project with Spring Boot where I need Arrays that contain groups of objects in JSON. It should look like this example:

{  
  &quot;Spring20&quot;: [
    {
      &quot;CSCXXX&quot;: &quot;Machine Learning&quot;,
       . . . 
    },
    {
      &quot;CSCXXX&quot;: &quot;Computer Vision&quot;,
       . . . 
    }
  ],  

  &quot;Fall20&quot;: [
    {
      &quot;EEXXX&quot;: &quot;Electronics&quot;,
       . . . 
    }
  ]
}

I tried using a Map that stores a String for the Array subject name and a List to hold all of the class objects. This is located in the service class.

 HashMap&lt;String, List&lt;Courses&gt;&gt; courseList = new HashMap&lt;String, List&lt;Courses&gt;&gt;();

[MODIFIED TO FIT SOLUTION]

Service

  public void add( Map&lt;String, List&lt;Courses&gt;&gt; course) {
        course.forEach((string, list) -&gt; {
             if(course_list.containsKey(semester)) {
                course_list.get(semester).addAll(course);
            } else {
                course_list.put(semester, course);
            }
        });  
    }
    public void edit(String semester, String id, Courses courses) {
          // Get the Course list from the Map
          List&lt;Courses&gt; updatedCourse = course_list.get(semester);
          // Loop and find the matching object within the list
          for(int i=0; i&lt;updatedCourse.size(); i++){
            if (updatedCourse.get(i).getID().equals(id)){
                // Once object found, update its values in the list 
                updatedCourse.get(i).set(course.getSubject())
                . . .
                // Finally, replace the list within the map
                course_list.replace(semester,  updatedCourse);
            }
        }
    }

Controller

    @RequestMapping(method=RequestMethod.POST, value=&quot;/add&quot;)
    public void addCourse(@RequestBody Map&lt;String, List&lt;Courses&gt;&gt; course) {
        service.addTest(course);
    }

    @RequestMapping(method=RequestMethod.PUT, value=&quot;/edit/{semster}/{id}&quot;)
    public void addCourse(@PathVariable(&quot;semester&quot;) String semester, @PathVariable(&quot;id&quot;) String id, @RequestBody Courses course) {
        service.editTest(semester, id, course);
    }

Everything works as expected when I add the JSON for the first time and I get the correct JSON structure. However, it becomes complex when adding and editing values.

  1. [SOLVED] Whenever I add a single object to an array, it replaces all the objects that were previously in the array. <strike>For instance, I have two objects in the "Spring 2020" array. If I make another POST request with addCourse(), both the objects get replaced</strike>
  2. [SOLVED] If I try to edit using postman, I get some exception
    <strike>
PUT: localhost:8080/edit/Spring20/
 &gt;&gt; &quot;message&quot;: &quot;Missing URI template variable &#39;semester&#39; for method parameter of type String&quot;,

I tried looking into this but I didn't find any useful links or examples where people categorize and organize their JSON using Spring Boot. If there's anything that can help, please comment below.
</strike>

EDIT
The solutions below helped fix these errors. I hope this post helps anyone who might be going through the same issues!

Here's another post I made that uses the Map<> with MongoDB.
https://stackoverflow.com/questions/64558958/crud-operations-on-array-objects-nested-within-an-object-in-mongodb-spring-boot

答案1

得分: 1

请看以下内容:

每当我向数组中添加一个单独的对象时,它会替换数组中先前存在的所有对象。例如,我在“春季2020”数组中有两个对象。如果我使用addCourse()进行另一个POST请求,那么这两个对象都会被替换。

问题在于你正在使用map.put()方法。使用此方法时,如果映射先前包含了该键的映射,旧值将被指定的值替换。因此,你的旧值被移除了。

解决方案是获取并更新现有条目。

public void add(Map<String, List<Courses>> course) {
    course.forEach((semester, list) -> {
        if (courseList.contains(semester)) {
            courseList.get(semester).addAll(list); // 注意,list可以接受重复项
        } else {
            courseList.put(semester, list);
        }
    });
}

如果我尝试使用postman进行编辑,会得到一些异常。
PUT: localhost:8080/edit/Spring20/
"message": "Missing URI template variable 'semester' for method parameter of type String",

问题在于你的路径变量名称 semester 与URL中的名称 semster 不匹配。因此,出现Missing URI template variable 'semester'错误。

@RequestMapping(method=RequestMethod.PUT, value="/edit/{semester}/{id}")
public void addCourse(@PathVariable("semester") String semester, @PathVariable("id") String id, @RequestBody Courses course) {
    service.editTest(semester, course);
}
英文:

Take a look at the following:
> Whenever I add a single object to an array, it replaces all the objects that were previously in the array. For instance, I have two objects in the "Spring 2020" array. If I make another POST request with addCourse(), both the objects get replaced.

The problem is that you are using map.put(). When using this method, if the map previously contained a mapping for the key, the old value is replaced by the specified value. Hence, your old values are removed.

The solution is to get and update the existing entry.

public void add( Map&lt;String, List&lt;Courses&gt;&gt; course) {
	course.forEach((semester, list) -&gt; {
		if(courseList.contains(semester)) {
			courseList.get(semester).addAll(list); // Note, list accepts duplicates
		} else {
			courseList.put(semester, list);
		}
	});
}

> If I try to edit using postman, I get some exception.
> PUT: localhost:8080/edit/Spring20/
> "message": "Missing URI template variable 'semester' for method parameter of type String",

The problem is that your path variable name semester does not match the name in the url semster. Hence, Missing URI template variable &#39;semester&#39;

@RequestMapping(method=RequestMethod.PUT, value=&quot;/edit/{semester}/{id}&quot;)
public void addCourse(@PathVariable(&quot;semester&quot;) String semester, @PathVariable(&quot;id&quot;) String id, @RequestBody Courses course) {
	service.editTest(semester, course);
}

huangapple
  • 本文由 发表于 2020年10月25日 10:27:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64519762.html
匿名

发表评论

匿名网友

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

确定