Upgrade the samples to Spring Boot 2.4.x
Closes gh-723
This commit is contained in:
@@ -18,6 +18,7 @@ package com.example.notes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
||||
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
@@ -28,8 +29,8 @@ class ExceptionSupressingErrorAttributes extends DefaultErrorAttributes {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getErrorAttributes(WebRequest webRequest,
|
||||
boolean includeStackTrace) {
|
||||
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
|
||||
ErrorAttributeOptions options) {
|
||||
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
|
||||
errorAttributes.remove("exception");
|
||||
Object message = webRequest.getAttribute("javax.servlet.error.message", RequestAttributes.SCOPE_REQUEST);
|
||||
if (message != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/")
|
||||
public class IndexController {
|
||||
class IndexController {
|
||||
|
||||
@RequestMapping(method=RequestMethod.GET)
|
||||
public ResourceSupport index() {
|
||||
ResourceSupport index = new ResourceSupport();
|
||||
public RepresentationModel<?> index() {
|
||||
RepresentationModel<?> index = new RepresentationModel<>();
|
||||
index.add(linkTo(NotesController.class).withRel("notes"));
|
||||
index.add(linkTo(TagsController.class).withRel("tags"));
|
||||
return index;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.Resources;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
|
||||
public class NestedContentResource<T> extends ResourceSupport {
|
||||
|
||||
private final Resources<T> nested;
|
||||
|
||||
public NestedContentResource(Iterable<T> toNest) {
|
||||
this.nested = new Resources<T>(toNest);
|
||||
}
|
||||
|
||||
@JsonUnwrapped
|
||||
public Resources<T> getNested() {
|
||||
return this.nested;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,8 +24,6 @@ import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Entity
|
||||
public class Note {
|
||||
|
||||
@@ -40,7 +38,6 @@ public class Note {
|
||||
@ManyToMany
|
||||
private List<Tag> tags;
|
||||
|
||||
@JsonIgnore
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -65,7 +62,6 @@ public class Note {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List<Tag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
@@ -73,4 +69,5 @@ public class Note {
|
||||
public void setTags(List<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import javax.validation.constraints.NotBlank;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class NoteInput {
|
||||
class NoteInput {
|
||||
|
||||
@NotBlank
|
||||
private final String title;
|
||||
@@ -35,23 +35,23 @@ public class NoteInput {
|
||||
private final List<URI> tagUris;
|
||||
|
||||
@JsonCreator
|
||||
public NoteInput(@JsonProperty("title") String title,
|
||||
NoteInput(@JsonProperty("title") String title,
|
||||
@JsonProperty("body") String body, @JsonProperty("tags") List<URI> tagUris) {
|
||||
this.title = title;
|
||||
this.body = body;
|
||||
this.tagUris = tagUris == null ? Collections.<URI>emptyList() : tagUris;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@JsonProperty("tags")
|
||||
public List<URI> getTagUris() {
|
||||
List<URI> getTagUris() {
|
||||
return this.tagUris;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class NotePatchInput {
|
||||
class NotePatchInput {
|
||||
|
||||
@NullOrNotBlank
|
||||
private final String title;
|
||||
@@ -33,23 +33,23 @@ public class NotePatchInput {
|
||||
private final List<URI> tagUris;
|
||||
|
||||
@JsonCreator
|
||||
public NotePatchInput(@JsonProperty("title") String title,
|
||||
NotePatchInput(@JsonProperty("title") String title,
|
||||
@JsonProperty("body") String body, @JsonProperty("tags") List<URI> tagUris) {
|
||||
this.title = title;
|
||||
this.body = body;
|
||||
this.tagUris = tagUris == null ? Collections.<URI>emptyList() : tagUris;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@JsonProperty("tags")
|
||||
public List<URI> getTagUris() {
|
||||
List<URI> getTagUris() {
|
||||
return this.tagUris;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,10 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface NoteRepository extends CrudRepository<Note, Long> {
|
||||
interface NoteRepository extends CrudRepository<Note, Long> {
|
||||
|
||||
Note findById(long id);
|
||||
|
||||
List<Note> findByTagsIn(Collection<Tag> tags);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
|
||||
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.hateoas.server.core.Relation;
|
||||
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.example.notes.NoteRepresentationModelAssembler.NoteModel;
|
||||
|
||||
@Component
|
||||
class NoteRepresentationModelAssembler extends RepresentationModelAssemblerSupport<Note, NoteModel> {
|
||||
|
||||
NoteRepresentationModelAssembler() {
|
||||
super(NotesController.class, NoteModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteModel toModel(Note entity) {
|
||||
NoteModel noteModel = createModelWithId(entity.getId(), entity);
|
||||
noteModel.add(linkTo(methodOn(NotesController.class).noteTags(entity.getId())).withRel("note-tags"));
|
||||
return noteModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NoteModel instantiateModel(Note entity) {
|
||||
return new NoteModel(entity);
|
||||
}
|
||||
|
||||
@Relation(collectionRelation = "notes", itemRelation = "note")
|
||||
static class NoteModel extends RepresentationModel<NoteModel> {
|
||||
|
||||
private final Note note;
|
||||
|
||||
NoteModel(Note note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.note.getTitle();
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return this.note.getBody();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.example.notes.NoteResourceAssembler.NoteResource;
|
||||
|
||||
@Component
|
||||
public class NoteResourceAssembler extends ResourceAssemblerSupport<Note, NoteResource> {
|
||||
|
||||
public NoteResourceAssembler() {
|
||||
super(NotesController.class, NoteResource.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteResource toResource(Note note) {
|
||||
NoteResource resource = createResourceWithId(note.getId(), note);
|
||||
resource.add(linkTo(NotesController.class).slash(note.getId()).slash("tags")
|
||||
.withRel("note-tags"));
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NoteResource instantiateResource(Note entity) {
|
||||
return new NoteResource(entity);
|
||||
}
|
||||
|
||||
static class NoteResource extends Resource<Note> {
|
||||
|
||||
public NoteResource(Note content) {
|
||||
super(content);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,15 +16,13 @@
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.CollectionModel;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -35,37 +33,34 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
import com.example.notes.NoteResourceAssembler.NoteResource;
|
||||
import com.example.notes.TagResourceAssembler.TagResource;
|
||||
import com.example.notes.NoteRepresentationModelAssembler.NoteModel;
|
||||
import com.example.notes.TagRepresentationModelAssembler.TagModel;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/notes")
|
||||
public class NotesController {
|
||||
class NotesController {
|
||||
|
||||
private static final UriTemplate TAG_URI_TEMPLATE = new UriTemplate("/tags/{id}");
|
||||
|
||||
private final NoteRepository noteRepository;
|
||||
|
||||
private final TagRepository tagRepository;
|
||||
|
||||
private final NoteRepresentationModelAssembler noteAssembler;
|
||||
|
||||
private final TagRepresentationModelAssembler tagAssembler;
|
||||
|
||||
private final NoteResourceAssembler noteResourceAssembler;
|
||||
|
||||
private final TagResourceAssembler tagResourceAssembler;
|
||||
|
||||
@Autowired
|
||||
public NotesController(NoteRepository noteRepository, TagRepository tagRepository,
|
||||
NoteResourceAssembler noteResourceAssembler,
|
||||
TagResourceAssembler tagResourceAssembler) {
|
||||
NotesController(NoteRepository noteRepository, TagRepository tagRepository,
|
||||
NoteRepresentationModelAssembler noteAssembler, TagRepresentationModelAssembler tagAssembler) {
|
||||
this.noteRepository = noteRepository;
|
||||
this.tagRepository = tagRepository;
|
||||
this.noteResourceAssembler = noteResourceAssembler;
|
||||
this.tagResourceAssembler = tagResourceAssembler;
|
||||
this.noteAssembler = noteAssembler;
|
||||
this.tagAssembler = tagAssembler;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
NestedContentResource<NoteResource> all() {
|
||||
return new NestedContentResource<NoteResource>(
|
||||
this.noteResourceAssembler.toResources(this.noteRepository.findAll()));
|
||||
CollectionModel<NoteModel> all() {
|
||||
return noteAssembler.toCollectionModel(this.noteRepository.findAll());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@@ -91,14 +86,13 @@ public class NotesController {
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||
Resource<Note> note(@PathVariable("id") long id) {
|
||||
return this.noteResourceAssembler.toResource(findNoteById(id));
|
||||
NoteModel note(@PathVariable("id") long id) {
|
||||
return this.noteAssembler.toModel(findNoteById(id));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}/tags", method = RequestMethod.GET)
|
||||
ResourceSupport noteTags(@PathVariable("id") long id) {
|
||||
return new NestedContentResource<TagResource>(
|
||||
this.tagResourceAssembler.toResources(findNoteById(id).getTags()));
|
||||
CollectionModel<TagModel> noteTags(@PathVariable("id") long id) {
|
||||
return this.tagAssembler.toCollectionModel(findNoteById(id).getTags());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ import org.hibernate.validator.constraints.ConstraintComposition;
|
||||
@NotBlank
|
||||
@Target({ ElementType.FIELD, ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NullOrNotBlank {
|
||||
@interface NullOrNotBlank {
|
||||
|
||||
String message() default "Must be null or not blank";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,6 @@
|
||||
package com.example.notes;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ResourceDoesNotExistException extends RuntimeException {
|
||||
class ResourceDoesNotExistException extends RuntimeException {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,16 +26,16 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestNotesControllerAdvice {
|
||||
class RestNotesControllerAdvice {
|
||||
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public void handleIllegalArgumentException(IllegalArgumentException ex,
|
||||
void handleIllegalArgumentException(IllegalArgumentException ex,
|
||||
HttpServletResponse response) throws IOException {
|
||||
response.sendError(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(ResourceDoesNotExistException.class)
|
||||
public void handleResourceDoesNotExistException(ResourceDoesNotExistException ex,
|
||||
void handleResourceDoesNotExistException(ResourceDoesNotExistException ex,
|
||||
HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
response.sendError(HttpStatus.NOT_FOUND.value(),
|
||||
"The resource '" + request.getRequestURI() + "' does not exist");
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class RestNotesSpringHateoas {
|
||||
class RestNotesSpringHateoas {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(RestNotesSpringHateoas.class, args);
|
||||
|
||||
@@ -24,8 +24,6 @@ import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Entity
|
||||
public class Tag {
|
||||
|
||||
@@ -38,7 +36,6 @@ public class Tag {
|
||||
@ManyToMany(mappedBy = "tags")
|
||||
private List<Note> notes;
|
||||
|
||||
@JsonIgnore
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -55,7 +52,6 @@ public class Tag {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public List<Note> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
@@ -63,4 +59,5 @@ public class Tag {
|
||||
public void setNotes(List<Note> notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,17 +21,17 @@ import javax.validation.constraints.NotBlank;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class TagInput {
|
||||
class TagInput {
|
||||
|
||||
@NotBlank
|
||||
private final String name;
|
||||
|
||||
@JsonCreator
|
||||
public TagInput(@NotBlank @JsonProperty("name") String name) {
|
||||
TagInput(@NotBlank @JsonProperty("name") String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,17 +19,17 @@ package com.example.notes;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class TagPatchInput {
|
||||
class TagPatchInput {
|
||||
|
||||
@NullOrNotBlank
|
||||
private final String name;
|
||||
|
||||
@JsonCreator
|
||||
public TagPatchInput(@NullOrNotBlank @JsonProperty("name") String name) {
|
||||
TagPatchInput(@NullOrNotBlank @JsonProperty("name") String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@ package com.example.notes;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface TagRepository extends CrudRepository<Tag, Long> {
|
||||
interface TagRepository extends CrudRepository<Tag, Long> {
|
||||
|
||||
Tag findById(long id);
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2014-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
|
||||
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.hateoas.server.core.Relation;
|
||||
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.example.notes.TagRepresentationModelAssembler.TagModel;
|
||||
|
||||
@Component
|
||||
class TagRepresentationModelAssembler extends RepresentationModelAssemblerSupport<Tag, TagModel> {
|
||||
|
||||
TagRepresentationModelAssembler() {
|
||||
super(TagsController.class, TagModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagModel toModel(Tag entity) {
|
||||
TagModel model = new TagModel(entity);
|
||||
model.add(linkTo(methodOn(TagsController.class).tag(entity.getId())).withSelfRel(),
|
||||
linkTo(methodOn(TagsController.class).tagNotes(entity.getId())).withRel("tagged-notes"));
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TagModel instantiateModel(Tag entity) {
|
||||
return new TagModel(entity);
|
||||
}
|
||||
|
||||
@Relation(collectionRelation = "tags", itemRelation = "tag")
|
||||
static class TagModel extends RepresentationModel<TagModel> {
|
||||
|
||||
private final Tag tag;
|
||||
|
||||
TagModel(Tag tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.tag.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.example.notes.TagResourceAssembler.TagResource;
|
||||
|
||||
@Component
|
||||
public class TagResourceAssembler extends ResourceAssemblerSupport<Tag, TagResource> {
|
||||
|
||||
public TagResourceAssembler() {
|
||||
super(TagsController.class, TagResource.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagResource toResource(Tag tag) {
|
||||
TagResource resource = createResourceWithId(tag.getId(), tag);
|
||||
resource.add(linkTo(TagsController.class).slash(tag.getId()).slash("notes")
|
||||
.withRel("tagged-notes"));
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TagResource instantiateResource(Tag entity) {
|
||||
return new TagResource(entity);
|
||||
}
|
||||
|
||||
static class TagResource extends Resource<Tag> {
|
||||
|
||||
public TagResource(Tag content) {
|
||||
super(content);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,9 @@
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.CollectionModel;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -30,32 +28,29 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.example.notes.NoteResourceAssembler.NoteResource;
|
||||
import com.example.notes.TagResourceAssembler.TagResource;
|
||||
import com.example.notes.NoteRepresentationModelAssembler.NoteModel;
|
||||
import com.example.notes.TagRepresentationModelAssembler.TagModel;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("tags")
|
||||
public class TagsController {
|
||||
class TagsController {
|
||||
|
||||
private final TagRepository repository;
|
||||
|
||||
private final TagRepresentationModelAssembler tagAssembler;
|
||||
|
||||
private final NoteRepresentationModelAssembler noteAssembler;
|
||||
|
||||
private final NoteResourceAssembler noteResourceAssembler;
|
||||
|
||||
private final TagResourceAssembler tagResourceAssembler;
|
||||
|
||||
@Autowired
|
||||
public TagsController(TagRepository repository,
|
||||
NoteResourceAssembler noteResourceAssembler,
|
||||
TagResourceAssembler tagResourceAssembler) {
|
||||
TagsController(TagRepository repository, TagRepresentationModelAssembler tagAssembler,
|
||||
NoteRepresentationModelAssembler noteAssembler) {
|
||||
this.repository = repository;
|
||||
this.noteResourceAssembler = noteResourceAssembler;
|
||||
this.tagResourceAssembler = tagResourceAssembler;
|
||||
this.tagAssembler = tagAssembler;
|
||||
this.noteAssembler = noteAssembler;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
NestedContentResource<TagResource> all() {
|
||||
return new NestedContentResource<TagResource>(
|
||||
this.tagResourceAssembler.toResources(this.repository.findAll()));
|
||||
CollectionModel<TagModel> all() {
|
||||
return this.tagAssembler.toCollectionModel(this.repository.findAll());
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@@ -78,16 +73,13 @@ public class TagsController {
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||
Resource<Tag> tag(@PathVariable("id") long id) {
|
||||
Tag tag = findTagById(id);
|
||||
return this.tagResourceAssembler.toResource(tag);
|
||||
TagModel tag(@PathVariable("id") long id) {
|
||||
return this.tagAssembler.toModel(findTagById(id));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}/notes", method = RequestMethod.GET)
|
||||
ResourceSupport tagNotes(@PathVariable("id") long id) {
|
||||
Tag tag = findTagById(id);
|
||||
return new NestedContentResource<NoteResource>(
|
||||
this.noteResourceAssembler.toResources(tag.getNotes()));
|
||||
CollectionModel<NoteModel> tagNotes(@PathVariable("id") long id) {
|
||||
return this.noteAssembler.toCollectionModel(findTagById(id).getNotes());
|
||||
}
|
||||
|
||||
private Tag findTagById(long id) {
|
||||
|
||||
Reference in New Issue
Block a user