Java 什么';通过Spring使用HTTP POST调用添加新对象的最佳方法是什么?
我正在学习Spring框架,并且正在与Spring的Rest服务进行斗争,特别是它应该向数据库添加新对象的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
@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(新电影);
}
}
为什么有些实现将参数aMap
?这是映射到键/值对的主体吗
还请记住,我成功地实现了正确的实现,只是实现#2,第一个和第三个给了我一个
415错误:“不支持的媒体类型”org.springframework.web.HttpMediaTypeNotSupportedException:内容类型“多部分/表单数据”;边界=------------------------------------901298977805450214809889;字符集=UTF-8'不受支持]
(尽管我跟随官员)在休息服务上
我还阅读了一些关于创建DTO类的内容,在这些类中,我可以定义属性,而无需将对象暴露给控制器,如何实现这样的解决方案?- 为什么有些实现将参数作为映射?
一些实现使用
,因为它们需要map接口提供的属性,如非重复键值,或者需要实现map接口的类,如map
和TreeMap
LinkedHashMap
- 关于类
的实现,我认为没有必要使用map在数据库中发布您的域,只要您有这个实现即可FilmController
实现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"
}