I followed this example, which allows to post a unique Person object. I want a REST service where I can post a collection of Person at once, e.g. a list/any collection named Team with numerous Person objects in just one call.
I mean, my question is not exactly about the OneToMany relationship, where you send each person in a REST request. This topic is well answered.
I want to send a collection of Person objects taking advantage of #RepositoryRestResource or another feature from Spring Data Rest. Is this possible with Spring Data Rest or should I workaround by creating a controller, receive the list and parse the Team list to insert each Person?
I found this feature request, which seems to answer that nowadays Spring Rest Data is missing what I am looking for, but I am not sure.
In my business requirement, application A will post a list of orders to application B and I have to save it in database for future processing, so, after reading about Spring Data Rest and making some samples, I found its clean architecture amazing and very suitable for my requirement except for the fact that I didn't figure out how to post a list.
Well, AFAIK you can't do that with spring data rest, just read the docs and you will see, that there is no mention about posting a list to collection resource.
The reason for this is unclear to me, but for one thing - the REST itself doesn't really specify how you should do batch operations.
So it's unclear how one should approach that feature, like should you POST a list to collection resource? Or should you export resource like /someentity/batch that would be able to patch, remove and add entities in one batch? If you will add list how should you return ids? For single POST to collection spring-data-rest return id in Location header. For batch add this cannot be done.
That doesn't justify that spring-data-rest is missing batch operations. They should implement this IMHO, but at least it can help to understand why are they missing it maybe.
What I can say though is that you can always add your own Controller to the project that would handle /someentity/batch properly and you can even probably make a library out of that, so that you can use it in another projects. Or even fork spring-data-rest and add this feature. Although I tried to understand how it works and failed so far.
But you probably know all that, right?
There is a feature request for this.
Based on user1685095 answer, You can make custom Controller PersonRestController and expose post collection of Person as it seem not exposed yet by Spring-date-rest
#RepositoryRestController
#RequestMapping(value = "/persons")
public class PersonRestController {
private final PersonRepository repo;
#Autowired
public AppointmentRestController(PersonRepository repo) {
this.repo = repo;
}
#RequestMapping(method = RequestMethod.POST, value = "/batch", consumes = "application/json", produces = "application/json")
public #ResponseBody ResponseEntity<?> savePersonList(#RequestBody Resource<PersonWrapper<Person>> personWrapper,
PersistentEntityResourceAssembler assembler) {
Resources<Person> resources = new Resources<Person>(repo.save(personWrapper.getContent()));
//TODO add extra links `assembler`
return ResponseEntity.ok(resources);
}
}
PersonWrapper to fix:
Can not deserialize instance of org.springframework.hateoas.Resources out of START_ARRAY token\n at [Source: java.io.PushbackInputStream#3298b722; line: 1, column: 1]
Update
public class PersonWrapper{
private List<Person> content;
public List<Person> getContent(){
return content;
}
public void setContent(List<Person> content){
this.content = content;
}
}
public class Person{
private String name;
private String email;
// Other fields
// GETTER & SETTER
}
I tried to use #RequestBody List<Resource<MyPojo>>.
When the request body does not contain any links, it works well, but
if the element carries a link, the server could not deserialize the request body.
Then I tried to use #RequestBody Resources<MyPojo>, but I could not figure out the default name of a list.
Finally, I tried a wrapper which contained List<Resource<MyPojo>>, and it works.
Here is my solution:
First create a wrapper class for List<Resource<MyPojo>>:
public class Bulk<T> {
private List<Resource<T>> bulk;
// getter and setter
}
Then use #RequestBody Resource<Bulk<MyPojo>> for parameters.
Finally, example json with links for create bulk data in one request:
{
"bulk": [
{
"title": "Spring in Action",
"author": "http://localhost:8080/authors/1"
},
{
"title": "Spring Quick Start",
"author": "http://localhost:8080/authors/2"
}
]
}
#RequestMapping(method=RequestMethod.POST, value="/batchInsert", consumes = "application/json", produces = "application/json")
#ResponseBody
public ResponseEntity<?> batchInsert(#RequestBody Resources<Person> people, PersistentEntityResourceAssembler assembler) throws Exception {
Iterable<Person> s = repo.save( people.getContent() ); // save entities
List<PersistentEntityResource> list = new ArrayList<PersistentEntityResource>();
Iterator<Sample> itr = s.iterator();
while(itr.hasNext()) {
list.add( assembler.toFullResource( itr.next() ) );
}
return ResponseEntity.ok( new Resources<PersistentEntityResource>(list) );
}
Base the answer of totran, this is my code:
There are dependencies:
springBootVersion = '2.4.2'
springDependencyManagement = '1.0.10.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
The codes:
import icu.kyakya.rest.jpa.model.Address;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
#RepositoryRestResource(collectionResourceRel = "address", path = "address")
public interface AddressRepository extends PagingAndSortingRepository<Address, Long> {
//...
}
import lombok.Data;
import java.util.List;
#Data
public class Bulk<T> {
private List<T> bulk;
}
import lombok.RequiredArgsConstructor;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.ExposesResourceFor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
#BasePathAwareController // if base url exists, it needs to be added
#RepositoryRestController
#RequiredArgsConstructor
#ExposesResourceFor(Address.class)
public class AddressController {
private final AddressRepository repo;
#PostMapping("/address/saveAll")
public ResponseEntity<Iterable<Address>> saveAll(#RequestBody EntityModel<Bulk<Address>> bulk) {
List<Address> addresses = Objects.requireNonNull(bulk.getContent()).getBulk();
Iterable<Address> resp = repo.saveAll(addresses);
return new ResponseEntity<>(resp,HttpStatus.CREATED);
}
}
The way more like Spring data rest:
import lombok.RequiredArgsConstructor;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.ExposesResourceFor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
#BasePathAwareController // if base url exists, it needs to be added
#RepositoryRestController
#RequiredArgsConstructor
#ExposesResourceFor(Address.class)
public class AddressController {
private final AddressRepository repo;
private final RepositoryEntityLinks entityLinks; //get link
/**
* curl -i -X POST -H "Content-Type:application/json" -d '{ "bulk": [ {"country" : "Japan" , "city" : "Tokyo" }, {"country" : "Japan" , "city" : "Osaka" }]} ' http://localhost:8080/api/v1/address/saveAll
*
* #return 201 https://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources.default-status-codes
*/
#PostMapping("/address/saveAll")
public ResponseEntity<CollectionModel<EntityModel<Address>>> List<Address> data = Objects.requireNonNull(bulk.getContent()).getBulk();
Iterable<Address> addresses = repo.saveAll(data);
ArrayList<EntityModel<Address>> models = new ArrayList<>();
addresses.forEach(i->{
Link link = entityLinks.linkToItemResource(Address.class, i.getId()).withRel("self");
models.add(EntityModel.of(i).add(link));
});
return new ResponseEntity<>(CollectionModel.of(models),HttpStatus.CREATED);
}
}
Related
I am trying to add the BusinessInformation data in my existing JSON.
{
"Original": "Web Form",
"SubmitterNetworkName": "null",
"SourceName": "Contact Request Form",
"SourceKind": "Web Form",
** "BusinessInformation": {
"BusinessContactName": null,
“AccountNumber”:null,
},**
"EmployeeName": null,
"EmployeeDOB": null,
}
So I have a Spring Batch app that exports data from a database to another DB and during that run some JSON needs to be created mapping multiple columns. I am using lombok and jackson mainly for the creation of JSON.
The model sample that I have. I also tried creating BusinessInformation class.
package model
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
#JsonIgnoreProperties(ignoreUnknown = true)
public class ColumnNameForTheDBImImportingTo implements Serializable {
#JsonProperty("Origin")
private String Origin;
and so on..
}
And then I have the Service for it.
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import twc.batch.extcbk.model.*;
import java.io.IOException;
#Component
#Slf4j
public class ColumnNameForTheDBImImportingToService {
private ColumnNameForTheDBImImportingTo columnNameForTheDBImImportingTo (some codes) {
ColumnNameForTheDBImImportingTo columnNameForTheDBImImportingTo = ColumnNameForTheDBImImportingTo .builder().build();
columnNameForTheDBImImportingTo.setOrigin("Web Form");
}
**Then I have a method for the object mapper.**
private String getColumnNameForTheDBImImportingTo (ColumnNameForTheDBImImportingTo columnNameForTheDBImImportingTo ) {
String columnNameForTheDBImImportingToStr = null;
try {
ObjectMapper mapper = new ObjectMapper();
columnNameForTheDBImImportingToStr = mapper.writeValueAsString(columnNameForTheDBImImportingTo );
log.debug("columnNameForTheDBImImportingToStr {}", columnNameForTheDBImImportingToStr );
} catch (IOException e) {
log.error("getColumnNameForTheDBImImportingTo " + e.getMessage());
}
return columnNameForTheDBImImportingToStr ;
}
**Then another class builds the db columns and sets the values.**
I've tried following the Baeldung but I don't quite understand it.
I tried creating a new class for the business information and i was thinking of inserting it in the ColumnNameForTheDBImImportingTo.
Please refer me to any useful information I can follow for this problem.
Thanks!
Data transformation is a typical use case for an item processor.
The way I would implement this with Spring Batch is configure a chunk-oriented step defined as follows:
A JsonItemReader to read the input file
An item processor that adds the business information
A JsonItemWriter to write the output file
Edit: I found a related question here, but the only 2 answers contradict each other, and there was not enough information to address my use case.
I am trying to use Spring Data Mongo to load records from a collection. One of the fields within those records is an Enum, defined as such:
#AllArgsConstructor
#Getter
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Action {
APPROVED("Approved"),
SAVED("Saved"),
CORRECTED("Corrected");
private String name;
#JsonCreator
static Action findValue(#JsonProperty("name") String name) {
return Arrays.stream(Action.values()).filter(v -> v.name.equals(name)).findFirst().get();
}
}
This should define enums to be serialized and deserialized according to a JSON representation: {"name": "Saved"} for example.
Jackson seems to be working fine, since I threw an API call at it and told it to expect an Action type, and it read the enum without any issues.
public void save(#RequestBody #Valid Action action) {
System.out.println(action.getName());
} // successfully prints the name of whatever Action I give
However, when I try to read an object with an Action field using Spring Data Mongo, I get the following:
Expected to read Document Document{{name=Corrected}} into type class package.structure.for.some.proprietary.stuff.constants.Action but didn't find a PersistentEntity for the latter!
So I'm thinking Spring Data Mongo just can't make heads or tails of these enums for whatever reason. But I'm not sure how to help it register that as a PersistentEntity. The main class of my Spring Boot app is in package package.structure.for.some.proprietary.stuff and is annotated as such:
#ComponentScan("package.structure")
#EnableTransactionManagement
#EnableAutoConfiguration
#SpringBootApplication
The object in particular I'm trying to read is defined by this POJO:
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Data;
import lombok.NonNull;
import package.structure.for.some.proprietary.stuff.constants.Action;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"timeStamp",
"action",
})
#Data
#Document(collection = "sample_coll")
public class Sample {
#Id
#JsonIgnore
private String id = null;
#JsonProperty("timeStamp")
#NonNull
private Date timeStamp;
#JsonProperty("action")
#NonNull
private Action action;
}
and is queried from the collection with a MongoRepository:
public interface SampleRepository extends MongoRepository<Sample, String> {
}
using SampleRepository.findAll();
So my big question is, how do I get Spring Data Mongo to recognize this enum Action as a PersistentEntity?
Try #Enumerated
#Enumerated
#JsonProperty("action")
#NonNull
private Action action;
I have a SQL table with schema
[student_id, standard, home_city, home_state, country, num_of_subjects]
Now, I want to support api end point over this table as below:
GET /students?home_state=?&country=?&home_city=?&standard=?
All the filters are optional.
Now, I want to know a good code design for this requirement. For technology I am using Java for web-app and a library querydsl for runtime query construction.
I have some ideas floating, but I'm looking for a concrete and extensible approach which can handle cases, so when a new filter column is added (let us say fav_subject), it should require minimum code changes.
For ideas, I am thinking of a Filter interface with a method
public interface Filter {
// If apiCallParameters contains this filter key, add filter to addToList
void addFilter(Map<String, String> apiCallParameters, List<QueryFilters> addToList);
}
All possible filters will be a class each, implementing this interface. Now, the query construction class can have List<Filter>, with each having addFilter deciding whether this filter will be added or not.
I want to better understand how this seemingly very common case is handled in code design.
The api you are describing maps to a REST interface. If you are looking for that kind of interface you could write something along these lines:
import org.springframework.stereotype.Service;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Context;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiParam;
#Service
#Path("/students")
public class StudentResource {
#GET
#Produces({MediaType.APPLICATION_JSON})
public JSONObject getStudent(#Context UriInfo uriInfo,
#ApiParam(required = false) #PathParam("home_state")String homeState,
#ApiParam(required = false) #PathParam("home_city")String homeCity,
#ApiParam(required = false) #PathParam("country")String country,
#ApiParam(required = false) #PathParam("standard")String standard)
{
// Do what you will with these strings which may be empty.
JSONObject obj = new JSONObject;
return obj;
}
}
I am having a very strange issue with a Rest Controller. I have a very basic rest controller.
package com.therealdanvega.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.therealdanvega.domain.Post;
import com.therealdanvega.service.PostService;
#RestController
public class PostController {
private PostService postService;
#Autowired
public PostController(PostService postService){
this.postService = postService;
}
#RequestMapping("posts/test")
public String test(){
return "test...";
}
#RequestMapping( name="/posts/", method=RequestMethod.GET )
public Iterable<Post> list(){
return postService.list();
}
}
That calls a service
package com.therealdanvega.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.therealdanvega.domain.Post;
import com.therealdanvega.repository.PostRepository;
#Service
public class PostService {
private PostRepository postRepository;
#Autowired
public PostService(PostRepository postRepository){
this.postRepository = postRepository;
}
public Iterable<Post> list(){
return postRepository.findAll();
}
}
That calls a repository to fetch the data.
package com.therealdanvega.repository;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.therealdanvega.domain.Post;
#Repository
public interface PostRepository extends CrudRepository<Post, Long> {
Post findFirstByOrderByPostedOnDesc();
List<Post> findAllByOrderByPostedOnDesc();
Post findBySlug(String slug);
}
I am using an H2 in memory database and I only have a single Post record in there and can confirm so by going to the H2 console and running a select again the Post table.
If I visit the /test URL I get exactly what I am expecting which is the string "test..." printed to the browser. If I try and list all of the posts (which again is only 1) the browser starts looping over and over and continue to print out a JSON representing of the 1 post so many times that the application crashes and I see this in the console
2015-11-07 17:58:42.959 ERROR 5546 --- [nio-8080-exec-1]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for
servlet dispatcherServlet threw exception
java.lang.IllegalStateException: getOutputStream() has already been
called for this response
This is what my browser looks like when I visit /posts which should only list 1
Post Domain Class
package com.therealdanvega.domain;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.data.annotation.CreatedDate;
#Entity
public class Post {
#Id #GeneratedValue
private Long id;
private String title;
#Column(columnDefinition = "TEXT")
private String body;
#Column(columnDefinition = "TEXT")
private String teaser;
private String slug;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date postedOn;
#ManyToOne
private Author author;
#SuppressWarnings("unused")
private Post(){
}
public Post(String title){
this.setTitle(title);
}
// getters & setters
}
Does anyone know what I am doing wrong or missing here? Why isn't it just display the 1 record in JSON format?
It seems that your Post object has a circular reference. The Author object in your Post object has a list of Posts objects and so on. Try putting the #JsonIgnore annotation on the author attribute of your post object.
You can also use the #JsonBackReference and #JsonManagedReference to solve the problem.
From the Jackson documentation :
Object references, identity
#JsonManagedReference, #JsonBackReference: pair of annotations used to
indicate and handle parent/child relationships expressed with pair of
matching properties #JsonIdentityInfo: class/property annotation used
to indicate that Object Identity is to be used when
serializing/deserializing values, such that multiple references to a
single Java Object can be properly deserialized. This can be used to
properly deal with cyclic object graphs and directed-acyclic graphs.
I believe your Posts domain object contains Author domain object, that in turn in it's posts field contains all the posts by that author, which in turn contains author that contains posts... you see where I'm going with this.
It's probably best that you use fetch or load graphs to optimize your query's fetch strategy.
I am using Jersey to implement JAX-RS REST-style services along with Jackson 2.0.2 for the JSON mapping. One of these REST services returns a List<EntityA> (let's call it indexA) where EntityA contains another List<EntityB> whereas another service just returns a List<EntityB> (let's call it indexB):
#Entity
#JsonAutoDetect
public class EntityA {
#Id
private String id;
#OneToMany
private List<EntityB> b;
...
}
#Entity
#JsonAutoDetect
#JsonFilter("bFilter")
public class EntityB {
#Id
private String id;
private String some;
private String other;
private String attributes;
...
}
#Path("/a")
public class AResource {
#GET
#Path("/")
public List<EntityA> indexA() {
...
}
}
#Path("/b")
public class BResource {
#GET
#Path("/")
public List<EntityB> indexB() {
...
}
}
What I'd like to achieve is to apply a Jackson filter to the indexA invocation so that not all attributes of the child EntityB elements are serialized. OTOH, indexB should return EntityB in its completeness.
I am aware of the existence of a ContextResolver<ObjectMapper>, which I am already using for other purposes. Unfortunately, for the ContextResolver it seems to be impossible to distinguish both service invocations as the Class supplied to ContextResolver.getContext(Class) is ArrayList in both cases (and thanks to type erasure I cannot figure out the generic type parameters).
Are there any hooks better suited at configuring an ObjectMapper/FilterProvider depending on the entity type that is being mapped?
I could use the approach proposed in How to return a partial JSON response using Java?: Manually mapping to a String, but that kills the whole beauty of a declarative annotation-based approach, so I'd like to avoid this.
I was in the same situation, after tons of research, I figured it out, the solution is to use #JsonView and Spring which can inject an ObjectMapper into the JSON Writer without killing the beauty of Jersey.
I am working on a set of REST APIs, I want to get a list of instances of SystemObject and the detail a specific instance of SystemObject, just like you I just want very limited of number of properties of each instance in the list and some additional properties in the detail, I just define Views for them, and add annotation in the SystemObject class. but by default, all properties with no #JsonView annotation will be output to the JSON, but there is a configuration item(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION) I can use to exclude them.
The problem is that I have to set it to true to meet my need. but I can not change the ObjectMapper which does the magic to convert the object to JSON, by reading the 3 articles below, I got the idea that the only way I can do is to inject a Modified ObjectMapper to Jersey.
Now I got what I want.
It is like you create multiple views against a database table.
These 3 links will help you in different ways:
How to create a ObjectMapperProvider which can be used by Spring to inject
Jersey, Jackson, Spring and JSON
Jersey + Spring integration example
REST resource:
package com.john.rest.resource;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import org.codehaus.jackson.map.annotate.JsonView;
import org.springframework.stereotype.Component;
import com.midtronics.esp.common.EspException;
import com.midtronics.esp.common.SystemObject;
import com.midtronics.esp.mobile.model.SystemObjectView;
import com.midtronics.esp.model.accesscontrol.AccessControlBean;
import com.midtronics.esp.model.site.SiteBean;
#Component
#Path("/hierarchy")
public class Hierarchy {
// Allows to insert contextual objects into the class,
// e.g. ServletContext, Request, Response, UriInfo
#Context
UriInfo uriInfo;
#Context
Request request;
// Return the list of sites
#GET
#Path("sites")
#Produces(MediaType.APPLICATION_JSON)
#JsonView({SystemObjectView.ObjectList.class})
public List<SystemObject> listSite(
#HeaderParam("userId") String userId,
#HeaderParam("password") String password) {
ArrayList<SystemObject> sites= new ArrayList<SystemObject>();
try{
if(!AccessControlBean.CheckUser(userId, password)){
throw new WebApplicationException(401);
}
SystemObject.GetSiteListByPage(sites, 2, 3);
return sites;
} catch(EspException e){
throw new WebApplicationException(401);
} catch (Exception e) {
throw new WebApplicationException(500);
}
}
// Return the number of sites
#GET
#Path("sites/total")
#Produces(MediaType.TEXT_PLAIN)
public String getSiteNumber(#HeaderParam("userId") String userId,
#HeaderParam("password") String password) {
try{
return Integer.toString(SiteBean.GetSiteTotal());
} catch(EspException e){
throw new WebApplicationException(401);
} catch (Exception e) {
throw new WebApplicationException(500);
}
}
}
REST model:
package com.john.rest.model;
import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonView;
import com.midtronics.esp.mobile.model.SystemObjectView;
import com.midtronics.esp.model.common.ICommonDAO;
#XmlRootElement
public class SystemObject implements Serializable
{
private static final long serialVersionUID = 3989499187492868996L;
#JsonProperty("id")
#JsonView({SystemObjectView.ObjectList.class, SystemObjectView.ObjectDetail.class})
protected String objectID = "";
#JsonProperty("parentId")
protected String parentID = "";
#JsonProperty("name")
#JsonView({SystemObjectView.ObjectList.class, SystemObjectView.ObjectDetail.class})
protected String objectName = "";
//getters...
//setters...
}
REST model view:
package com.john.rest.model;
public class SystemObjectView {
public static class ObjectList { };
public static class ObjectDetail extends ObjectList { }
}