From 89defddb4248f55731077df5f08d1edf15ddb309 Mon Sep 17 00:00:00 2001 From: Vitaliy Fedoriv Date: Sat, 15 Oct 2016 20:08:26 +0300 Subject: [PATCH] add Owner and Vets REST controllers; add @JsonIdentityInfo for avoid infinite loop on serialization --- .../samples/petclinic/model/Owner.java | 9 +- .../samples/petclinic/model/Pet.java | 26 ++--- .../petclinic/rest/OwnerRestController.java | 98 +++++++++++++++++++ .../petclinic/rest/VetRestController.java | 54 ++++++++++ .../samples/petclinic/rest/package-info.java | 5 + src/main/resources/spring/mvc-core-config.xml | 5 +- 6 files changed, 182 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java create mode 100644 src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java create mode 100644 src/main/java/org/springframework/samples/petclinic/rest/package-info.java diff --git a/src/main/java/org/springframework/samples/petclinic/model/Owner.java b/src/main/java/org/springframework/samples/petclinic/model/Owner.java index d0158d907..902f6493c 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Owner.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Owner.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 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,6 +24,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.Digits; @@ -33,6 +34,9 @@ import org.springframework.beans.support.MutableSortDefinition; import org.springframework.beans.support.PropertyComparator; import org.springframework.core.style.ToStringCreator; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + /** * Simple JavaBean domain object representing an owner. * @@ -43,6 +47,7 @@ import org.springframework.core.style.ToStringCreator; */ @Entity @Table(name = "owners") +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Owner extends Person { @Column(name = "address") @NotEmpty @@ -57,7 +62,7 @@ public class Owner extends Person { @Digits(fraction = 0, integer = 10) private String telephone; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch = FetchType.EAGER) private Set pets; diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index 0cbf975fa..4481e9985 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -15,9 +15,12 @@ */ package org.springframework.samples.petclinic.model; -import org.springframework.beans.support.MutableSortDefinition; -import org.springframework.beans.support.PropertyComparator; -import org.springframework.format.annotation.DateTimeFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -27,15 +30,15 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; - import javax.persistence.Temporal; import javax.persistence.TemporalType; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; + +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; +import org.springframework.format.annotation.DateTimeFormat; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; /** * Simple business object representing a pet. @@ -46,6 +49,7 @@ import java.util.Set; */ @Entity @Table(name = "pets") +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Pet extends NamedEntity { @Column(name = "birth_date") diff --git a/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java new file mode 100644 index 000000000..794035708 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/OwnerRestController.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 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 + * + * http://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 org.springframework.samples.petclinic.rest; + +import java.util.Collection; + +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.model.Owner; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PathVariable; +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.util.UriComponentsBuilder; + +/** + * @author Vitaliy Fedoriv + * + */ + +@RestController +@RequestMapping("/api/owners") +public class OwnerRestController { + + @Autowired + private ClinicService clinicService; + + @RequestMapping(value = "/}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> getAllOwners(){ + Collection owners = this.clinicService.findOwnerByLastName(""); + if(owners.isEmpty()){ + return new ResponseEntity>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity>(owners, HttpStatus.OK); + } + + @RequestMapping(value = "/{ownerId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity getOwner(@PathVariable("ownerId") int ownerId){ + Owner owner = this.clinicService.findOwnerById(ownerId); + if(owner == null){ + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + return new ResponseEntity(owner, HttpStatus.OK); + } + + @RequestMapping(value = "/", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity addOwner(@RequestBody @Valid Owner owner, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ + if(bindingResult.hasErrors() || (owner == null)){ + return new ResponseEntity(HttpStatus.BAD_REQUEST); + } + this.clinicService.saveOwner(owner); + HttpHeaders headers = new HttpHeaders(); + headers.setLocation(ucBuilder.path("/owners/{id}").buildAndExpand(owner.getId()).toUri()); + return new ResponseEntity(headers, HttpStatus.CREATED); + } + + @RequestMapping(value = "/{ownerId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody @Valid Owner owner, BindingResult bindingResult, UriComponentsBuilder ucBuilder){ + if(bindingResult.hasErrors() || (owner == null)){ + return new ResponseEntity(HttpStatus.BAD_REQUEST); + } + Owner currentOwner = this.clinicService.findOwnerById(ownerId); + if(currentOwner == null){ + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + currentOwner.setAddress(owner.getAddress()); + currentOwner.setCity(owner.getCity()); + currentOwner.setFirstName(owner.getFirstName()); + currentOwner.setLastName(owner.getLastName());; + currentOwner.setTelephone(owner.getTelephone()); + this.clinicService.saveOwner(currentOwner); + return new ResponseEntity(currentOwner, HttpStatus.OK); + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java new file mode 100644 index 000000000..0c8d0694a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/VetRestController.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 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 + * + * http://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 org.springframework.samples.petclinic.rest; + +import java.util.ArrayList; +import java.util.Collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.samples.petclinic.model.Vet; +import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Vitaliy Fedoriv + * + */ + +@RestController +@RequestMapping("api/vets") +public class VetRestController { + + @Autowired + private ClinicService clinicService; + + @RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> getAllVets(){ + Collection vets = new ArrayList(); + vets.addAll(this.clinicService.findVets()); + if (vets.isEmpty()){ + return new ResponseEntity>(HttpStatus.NOT_FOUND); + } + return new ResponseEntity>(vets, HttpStatus.OK); + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/rest/package-info.java b/src/main/java/org/springframework/samples/petclinic/rest/package-info.java new file mode 100644 index 000000000..dfae7ea5a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/rest/package-info.java @@ -0,0 +1,5 @@ +/** + * The classes in this package represent PetClinic's REST API. + */ + +package org.springframework.samples.petclinic.rest; \ No newline at end of file diff --git a/src/main/resources/spring/mvc-core-config.xml b/src/main/resources/spring/mvc-core-config.xml index 6e254423f..b1e21d002 100644 --- a/src/main/resources/spring/mvc-core-config.xml +++ b/src/main/resources/spring/mvc-core-config.xml @@ -19,9 +19,10 @@ - + +