Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';通过Spring使用HTTP POST调用添加新对象的最佳方法是什么?_Java_Spring_Spring Boot_Rest_Spring Mvc - Fatal编程技术网

Java 什么';通过Spring使用HTTP POST调用添加新对象的最佳方法是什么?

Java 什么';通过Spring使用HTTP POST调用添加新对象的最佳方法是什么?,java,spring,spring-boot,rest,spring-mvc,Java,Spring,Spring Boot,Rest,Spring Mvc,我正在学习Spring框架,并且正在与Spring的Rest服务进行斗争,特别是它应该向数据库添加新对象的POST调用。 我在网上看到了很多不同的实现,但我不知道如何挑选最好的 让我们以电影课为例: @Entity public class Film { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String title; private String desc

我正在学习Spring框架,并且正在与Spring的Rest服务进行斗争,特别是它应该向数据库添加新对象的POST调用。 我在网上看到了很多不同的实现,但我不知道如何挑选最好的

让我们以电影课为例:

@Entity
public class Film {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  private String title;

  private String description;

  //Constructor, Getter and Setter Omitted.
}
假设存储库扩展了JpaRepository,这将是控制器类:

@RestController
public class FilmController {

  @Autowired
  FilmRepository filmRepository;
 
  //Implementation #1
  @PostMapping("/film")
  public Film addNew(@RequestBody Map<String,String> body){
    String title = body.get("title");
    String description = body.get("description");
    return filmRepository.save(new Film(title,description));
  }
  
  //Implementation #2
  @PostMapping("/film")
  public Film addNew(String title, String description){
    Film film = new Film(title,description);
    System.out.println(film.getTitle() + " " + film.getDescription());
    return filmRepository.save(film);
  }

  //Implementation #3
  @PostMapping("/film")
  public Film addNew(@RequestBody Film newFilm){
    return filmRepository.save(newFilm);
  }

}
@RestController
公共类电影控制员{
@自动连线
电影知识库;
//实施#1
@后期贴图(“/胶片”)
公共电影addNew(@RequestBody-Map-body){
字符串title=body.get(“title”);
字符串描述=body.get(“描述”);
返回filmRepository.save(新电影(标题、描述));
}
//实施#2
@后期贴图(“/胶片”)
公共电影addNew(字符串标题、字符串描述){
电影=新电影(标题、描述);
System.out.println(film.getTitle()+“”+film.getDescription());
返回电影存储库。保存(电影);
}
//实施#3
@后期贴图(“/胶片”)
公共电影addNew(@RequestBody-Film-newFilm){
返回filmRepository.save(新电影);
}
}
为什么有些实现将参数a
Map
?这是映射到键/值对的主体吗

还请记住,我成功地实现了正确的实现,只是实现#2,第一个和第三个给了我一个

415错误:“不支持的媒体类型”org.springframework.web.HttpMediaTypeNotSupportedException:内容类型“多部分/表单数据”;边界=------------------------------------901298977805450214809889;字符集=UTF-8'不受支持]

(尽管我跟随官员)在休息服务上

我还阅读了一些关于创建DTO类的内容,在这些类中,我可以定义属性,而无需将对象暴露给控制器,如何实现这样的解决方案?

  • 为什么有些实现将参数作为映射?
    一些实现使用
    map
    ,因为它们需要map接口提供的属性,如非重复键值,或者需要实现map接口的类,如
    TreeMap
    LinkedHashMap
  • 关于类
    FilmController
    的实现,我认为没有必要使用map在数据库中发布您的域,只要您有这个实现即可

实现3是最佳实践,但您应该创建一个轻量级DTO类(可能是FilmDto),以避免暴露实体的内部结构,请参见

您可以使用将FilmDto映射到Film,并确保两个类中都有适当的getter和setter,如果getter和setter在两个类中具有相同的名称,则ModelMapper将顺利进行转换:

public class FilmDto {
    private long id;
    private String title;
    private String description;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
而你的控制员:

@RestController
@RequestMapping("/api")
public class FilmController {

    private final FilmRepository filmRepository;
    private ModelMapper modelMapper = new ModelMapper();
    @Autowired
    public FilmController(FilmRepository filmRepository) {
        this.filmRepository = filmRepository;
    }


    //Implementation #3
    @PostMapping("/film")
    public ResponseEntity<FilmDto> addNew(@RequestBody FilmDto  filmDto){
        Film newFilm = modelMapper.map(filmDto, Film.class);
        newFilm = filmRepository.save(newFilm);
        filmDto.setId(newFilm.getId());//you may use modelMapper here

        return ResponseEntity.ok(filmDto);
    }
}

主体应该是“raw”,“JSON”类型。

我更新了答案。现在你应该可以将你的对象发布到数据库了谢谢你,pooya,不幸的是,你的第一个要点还不清楚。哪个类实现映射接口?我假设JpaRepository类中有一些方法,对吗?谢谢Bassem!真的很有帮助。是的,我刚刚意识到,如果我使用JSON“raw”类型的body(我使用的是Postman),它是有效的。我看到过使用表单数据的教程,在我的例子中,它不起作用。JSON/表单数据之间有什么区别?如何使@RestController表单数据兼容?再次感谢你。
@RestController
@RequestMapping("/api")
public class FilmController {

    private final FilmRepository filmRepository;
    private ModelMapper modelMapper = new ModelMapper();
    @Autowired
    public FilmController(FilmRepository filmRepository) {
        this.filmRepository = filmRepository;
    }


    //Implementation #3
    @PostMapping("/film")
    public ResponseEntity<FilmDto> addNew(@RequestBody FilmDto  filmDto){
        Film newFilm = modelMapper.map(filmDto, Film.class);
        newFilm = filmRepository.save(newFilm);
        filmDto.setId(newFilm.getId());//you may use modelMapper here

        return ResponseEntity.ok(filmDto);
    }
}
{
    "title": "some title",
    "description": "some description"
}