From 82f596b9f3a5cf0ac4abdd02c9e99b64b8b16e4b Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Mon, 12 Mar 2018 15:20:04 +0100 Subject: [PATCH] Set Id and Revision HTTP headers for POST, PUT and PATCH responses --- .../controller/AbstractEntityController.java | 27 ++++++++++++++++--- .../arsnova/controller/AnswerController.java | 9 ++++++- .../arsnova/controller/CommentController.java | 9 ++++++- .../arsnova/controller/ContentController.java | 8 +++++- .../arsnova/controller/MotdController.java | 9 ++++++- .../arsnova/controller/RoomController.java | 9 ++++++- .../arsnova/controller/UserController.java | 9 ++++++- 7 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/thm/arsnova/controller/AbstractEntityController.java b/src/main/java/de/thm/arsnova/controller/AbstractEntityController.java index ed7c1d38c..7876d0163 100644 --- a/src/main/java/de/thm/arsnova/controller/AbstractEntityController.java +++ b/src/main/java/de/thm/arsnova/controller/AbstractEntityController.java @@ -24,6 +24,8 @@ import de.thm.arsnova.services.FindQueryService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; @@ -32,8 +34,11 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.util.UriComponentsBuilder; import javax.naming.OperationNotSupportedException; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; import java.util.Map; @@ -47,6 +52,8 @@ import java.util.Set; */ public abstract class AbstractEntityController<E extends Entity> { private static final Logger logger = LoggerFactory.getLogger(AbstractEntityController.class); + protected static final String ENTITY_ID_HEADER = "Arsnova-Entity-Id"; + protected static final String ENTITY_REVISION_HEADER = "Arsnova-Entity-Revision"; protected static final String DEFAULT_ROOT_MAPPING = "/"; protected static final String DEFAULT_ID_MAPPING = "/{id}"; protected static final String DEFAULT_FIND_MAPPING = "/find"; @@ -64,6 +71,8 @@ public abstract class AbstractEntityController<E extends Entity> { this.entityService = entityService; } + protected abstract String getMapping(); + @GetMapping(GET_MAPPING) public E get(@PathVariable final String id) { return entityService.get(id); @@ -75,21 +84,31 @@ public abstract class AbstractEntityController<E extends Entity> { } @PutMapping(PUT_MAPPING) - public void put(@RequestBody final E entity) { + public void put(@RequestBody final E entity, final HttpServletResponse httpServletResponse) { E oldEntity = entityService.get(entity.getId()); entityService.update(oldEntity, entity); + httpServletResponse.setHeader(ENTITY_ID_HEADER, entity.getId()); + httpServletResponse.setHeader(ENTITY_REVISION_HEADER, entity.getRevision()); } @PostMapping(POST_MAPPING) - public void post(@RequestBody final E entity) { + @ResponseStatus(HttpStatus.CREATED) + public void post(@RequestBody final E entity, final HttpServletResponse httpServletResponse) { entityService.create(entity); + final String uri = UriComponentsBuilder.fromPath(getMapping()).path(GET_MAPPING) + .buildAndExpand(entity.getId()).toUriString(); + httpServletResponse.setHeader(HttpHeaders.LOCATION, uri); + httpServletResponse.setHeader(ENTITY_ID_HEADER, entity.getId()); + httpServletResponse.setHeader(ENTITY_REVISION_HEADER, entity.getRevision()); } @PatchMapping(PATCH_MAPPING) - public void patch(@PathVariable final String id, @RequestBody final Map<String, Object> changes) - throws IOException { + public void patch(@PathVariable final String id, @RequestBody final Map<String, Object> changes, + final HttpServletResponse httpServletResponse) throws IOException { E entity = entityService.get(id); entityService.patch(entity, changes); + httpServletResponse.setHeader(ENTITY_ID_HEADER, entity.getId()); + httpServletResponse.setHeader(ENTITY_REVISION_HEADER, entity.getRevision()); } @DeleteMapping(DELETE_MAPPING) diff --git a/src/main/java/de/thm/arsnova/controller/AnswerController.java b/src/main/java/de/thm/arsnova/controller/AnswerController.java index 8eeb8e736..d0fd8606c 100644 --- a/src/main/java/de/thm/arsnova/controller/AnswerController.java +++ b/src/main/java/de/thm/arsnova/controller/AnswerController.java @@ -23,12 +23,19 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/answer") +@RequestMapping(AnswerController.REQUEST_MAPPING) public class AnswerController extends AbstractEntityController<Answer> { + protected static final String REQUEST_MAPPING = "/answer"; + private AnswerService answerService; public AnswerController(final AnswerService answerService) { super(answerService); this.answerService = answerService; } + + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } } diff --git a/src/main/java/de/thm/arsnova/controller/CommentController.java b/src/main/java/de/thm/arsnova/controller/CommentController.java index cfcb1579c..ea66759d7 100644 --- a/src/main/java/de/thm/arsnova/controller/CommentController.java +++ b/src/main/java/de/thm/arsnova/controller/CommentController.java @@ -23,12 +23,19 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/comment") +@RequestMapping(CommentController.REQUEST_MAPPING) public class CommentController extends AbstractEntityController<Comment> { + protected static final String REQUEST_MAPPING = "/comment"; + private CommentService commentService; public CommentController(final CommentService commentService) { super(commentService); this.commentService = commentService; } + + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } } diff --git a/src/main/java/de/thm/arsnova/controller/ContentController.java b/src/main/java/de/thm/arsnova/controller/ContentController.java index 1ba72f9b9..3856ed20a 100644 --- a/src/main/java/de/thm/arsnova/controller/ContentController.java +++ b/src/main/java/de/thm/arsnova/controller/ContentController.java @@ -27,8 +27,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/content") +@RequestMapping(ContentController.REQUEST_MAPPING) public class ContentController extends AbstractEntityController<Content> { + protected static final String REQUEST_MAPPING = "/content"; private static final String GET_ANSWER_STATISTICS_MAPPING = DEFAULT_ID_MAPPING + "/stats"; private ContentService contentService; @@ -40,6 +41,11 @@ public class ContentController extends AbstractEntityController<Content> { this.answerService = answerService; } + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } + @GetMapping(GET_ANSWER_STATISTICS_MAPPING) public AnswerStatistics getAnswerStatistics(@PathVariable final String id) { return answerService.getAllStatistics(id); diff --git a/src/main/java/de/thm/arsnova/controller/MotdController.java b/src/main/java/de/thm/arsnova/controller/MotdController.java index 1a3df379a..7193fc3b0 100644 --- a/src/main/java/de/thm/arsnova/controller/MotdController.java +++ b/src/main/java/de/thm/arsnova/controller/MotdController.java @@ -23,12 +23,19 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/motd") +@RequestMapping(MotdController.REQUEST_MAPPING) public class MotdController extends AbstractEntityController<Motd> { + protected static final String REQUEST_MAPPING = "/motd"; + private MotdService motdService; public MotdController(final MotdService motdService) { super(motdService); this.motdService = motdService; } + + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } } diff --git a/src/main/java/de/thm/arsnova/controller/RoomController.java b/src/main/java/de/thm/arsnova/controller/RoomController.java index 5f0797fbf..21fe4a851 100644 --- a/src/main/java/de/thm/arsnova/controller/RoomController.java +++ b/src/main/java/de/thm/arsnova/controller/RoomController.java @@ -23,12 +23,19 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/room") +@RequestMapping(RoomController.REQUEST_MAPPING) public class RoomController extends AbstractEntityController<Room> { + protected static final String REQUEST_MAPPING = "/room"; + private RoomService roomService; public RoomController(final RoomService roomService) { super(roomService); this.roomService = roomService; } + + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } } diff --git a/src/main/java/de/thm/arsnova/controller/UserController.java b/src/main/java/de/thm/arsnova/controller/UserController.java index b68b60a04..de5a94673 100644 --- a/src/main/java/de/thm/arsnova/controller/UserController.java +++ b/src/main/java/de/thm/arsnova/controller/UserController.java @@ -9,8 +9,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/user") +@RequestMapping(UserController.REQUEST_MAPPING) public class UserController extends AbstractEntityController<UserProfile> { + protected static final String REQUEST_MAPPING = "/user"; + private UserService userService; public UserController(final UserService userService) { @@ -18,6 +20,11 @@ public class UserController extends AbstractEntityController<UserProfile> { this.userService = userService; } + @Override + protected String getMapping() { + return REQUEST_MAPPING; + } + @PostMapping("/register") public void register(@RequestBody LoginCredentials loginCredentials) { userService.create(loginCredentials.getLoginId(), loginCredentials.getPassword()); -- GitLab