我想在Spring中公开一些REST资源,默认情况下我可以让Spring Boot处理这个问题,这会产生一个很好的HATEOAS响应,我可以获得所有内容' free'。
现在我需要在某个资源被POSTED时执行一些逻辑,所以我实现了自己的@RestController类并覆盖了POST方法,如下所示:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import java.net.URI;
import java.security.Principal;
@RestController
@RequestMapping(Constants.PROJECTSPATH)
public class ProjectController {
@Autowired private ProjectRepository projectRepo;
@Autowired private ProjectRoleRepository projectRoleRepo;
@Autowired private AccountRepository accountRepo;
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addProject(@RequestBody Project projectFromRequest, Principal principal) {
Project project = projectRepo.save(projectFromRequest);
Account currentAccount = accountRepo.findByUsername(principal.getName());
ProjectRole ownerRole = new ProjectRole(project, currentAccount, ProjectRoleEnum.OWNER);
projectRoleRepo.save(ownerRole);
final URI uri =
MvcUriComponentsBuilder.fromController(getClass())
.path("/{id}")
.buildAndExpand(project.getId())
.toUri();
return ResponseEntity.created(uri).body(new ProjectResource(project));
}
}
我使用从ResourceSupport继承的类,在那里我为HATEOAS响应生成所需的链接。到目前为止一切都很好,这不是太多的定制工作。
问题在于,如果我现在只是尝试获取所有项目,我会收到以下消息:
{&#34; timestamp&#34;:1518610270403,&#34; status&#34;:405,&#34; error&#34;:&#34; Method Not Not 允许&#34;&#34;例外&#34;:&#34; org.springframework.web.HttpRequestMethodNotSupportedException&#34;&#34;消息&#34;:&#34;请求 方法&#39; GET&#39;不支持&#34;,&#34;路径&#34;:&#34; / projects&#34;}
我真的不想实现其他方法,Spring Boot默认完成。但我现在也被迫实施这些并且每次都更改我的整个HATEOAS响应,我的域对象会更改吗?这是我喜欢的功能,开箱即用&#39;。
答案 0 :(得分:2)
如何在@RestController中仅覆盖1个Http方法(POST),但让Spring使用标准的HATEOAS响应处理所有其他Http方法
你不能用@RestController
做到这一点。如Spring Data REST reference中所述:
有时您可能希望为特定资源编写自定义处理程序。要利用Spring Data REST的设置,消息转换器,异常处理等,请使用
@RepositoryRestController
注释而不是标准的Spring MVC @Controller或@RestController
没有明确提及,但使用@RepositoryRestController
注释控制器允许您为一个端点定义自定义行为,同时保留Spring自动生成的所有其他端点。但重要的是,在method level only使用@RequestMapping
注释。
你的例子变成了:
@RepositoryRestController
public class ProjectController {
@Autowired private ProjectRepository projectRepo;
@Autowired private ProjectRoleRepository projectRoleRepo;
@Autowired private AccountRepository accountRepo;
@PostMapping(Constants.PROJECTSPATH) // @PostMapping is a shortcut for @RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addProject(@RequestBody Project projectFromRequest, Principal principal) {
Project project = projectRepo.save(projectFromRequest);
Account currentAccount = accountRepo.findByUsername(principal.getName());
ProjectRole ownerRole = new ProjectRole(project, currentAccount, ProjectRoleEnum.OWNER);
projectRoleRepo.save(ownerRole);
final URI uri =
MvcUriComponentsBuilder.fromController(getClass())
.path("/{id}")
.buildAndExpand(project.getId())
.toUri();
return ResponseEntity.created(uri).body(new ProjectResource(project));
}
}