my URI is
http://localhost:8080/context/my-objects/search/findByCode?code=foo
JSON response:
{
"_embedded" : {
"my-objects" : [ {
"code" : "foo",
"description" : "foo description",
"_links" : {
"self" : {
"href" : "http://localhost:8080/context/my-objects/34"
}
}
} ]
}
}
How can I get a java MyObject with Traverson or RestTemplate?
import org.springframework.hateoas.ResourceSupport;
public class MyObject extends ResourceSupport{
private String code;
private String description;
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(final String code) {
this.code = code;
}
}
This is my Template. I've also tried with a default one.
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate(Collections.<HttpMessageConverter<?>> singletonList(converter));
}
Thx in advance.
I've found the solution. First, create a Resources class:
import org.springframework.hateoas.Resources;
public class MyObjects extends Resources<MyObject> { }
Then it is straightforward:
MyObjects myObjects = template.getForObject("http://localhost:8080/context/my-objects/search/findByCode?code=foo", MyObjects.class);
Attention: the template should support hal+json Media Type.
Or with Traverson:
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.client.Traverson;
Traverson traverson;
try{
traverson = new Traverson(new URI("http://localhost:8080/context"), MediaTypes.HAL_JSON);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("code", "foo");
MyObjects myObjects = traverson.follow("my-objects", "search", "findByCode").withTemplateParameters(
parameters).toObject(MyObjects.class);
} catch (URISyntaxException e) {}
If you don't want to extend your POJO MyObject with ResourceSupport class, your Resources class should be typed with Resource:
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.Resources;
public class MyObjects extends Resources<Resource<MyObject>> { }
(If you don't need links the type parameter may again be MyObject).
Related
How can I add my own ArangoDB configuration converter.
An example of a converter.
public class HTMLConverter {
private static final boolean HTML_DESCRIPTION_IS_PRESENT = ClassUtils.isPresent("com.b.k.api.domain.extend.HTML", null);
public static Collection<Converter<?, ?>> getConvertersToRegister() {
if (!HTML_DESCRIPTION_IS_PRESENT) {
return Collections.emptySet();
}
final List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(HtmlToStringConverter.INSTANCE);
converters.add(StringToHtmlConverter.INSTANCE);
return converters;
}
public enum HtmlToStringConverter implements Converter<HTML, String> {
INSTANCE;
#Override
public String convert(final HTML source) {
return source == null ? null : source.getXml();
}
}
public enum StringToHtmlConverter implements Converter<String, HTML> {
INSTANCE;
#Override
public HTML convert(final String source) {
return source == null ? null : new HTML(source);
}
}
}
The reproduction of my converters looks like this:
public class BKArangoCustomConverters extends CustomConversions {
private static final StoreConversions STORE_CONVERSIONS;
static {
final Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
STORE_CONVERSIONS = StoreConversions.of(SimpleTypeHolder.DEFAULT, converters);
}
protected BKArangoCustomConverters(Collection<?> converters) {
super(converters);
}
}
I am asked how can I add new converters to the ArangoDB configuration using the builder "com.arangodb.ArangoDB.Builder" in the extension class "com.arangodb.springframework.config.AbstractArangoConfiguration".
You have to override the method customConversions() from AbstractArangoConfiguration in your configuration class and add your converters there.
public CustomConversions customConversions() {
Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
return new ArangoCustomConversions(converters);
}
or you replace the ArangoCustomConversions with our own clasn class BKArangoCustomConverters.
public CustomConversions customConversions() {
return new BKArangoCustomConverters(Collections.emptyList());
}
I have created a rest Service using Apache Camel Swagger component. The rest service works fine but the request and response schema is not what i intended of.
The schema that i am trying to create is :
{
"GetStudentData": [
{
"RollNumber": "1",
"Name": "ABC",
"ClassName": "VII",
"Grade": "A"
}]
}
For this i have created a model as:
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "GetStudentData")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name="", propOrder={"studentInfo"})
public class StudentInfoWrapper {
#XmlElement(required=true)
private List<Student> studentInfo;
private double visiteddate;
public double getVisiteddate() {
return visiteddate;
}
public void setVisiteddate(double visiteddate) {
this.visiteddate = visiteddate;
}
public List<Student> getStudentInfo() {
return studentInfo;
}
public void setStudentInfo(List<Student> studentInfo) {
studentInfo = studentInfo;
}
}
And my student class is:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name="", propOrder={"RollNumber", "Name", "ClassName", "Grade"})
public class Student {
private String RollNumber;
private String Name;
private String ClassName;
private String Grade;
public String getRollNumber() {
return RollNumber;
}
public void setRollNumber(String rollNumber) {
RollNumber = rollNumber;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getClassName() {
return ClassName;
}
public void setClassName(String className) {
ClassName = className;
}
public String getGrade() {
return Grade;
}
public void setGrade(String grade) {
Grade = grade;
}
}
So when i load the above service into the swaggerUI it doesn't show the schema that i want.
How can i i get the desired schema. Looking forward to your answers.
Thanks in advance.
I'm using orientdb-object-2.1.9 and trying to setup a basic repository to save and find objects.
But when accessing any property of the returned object from the database, it throws an ODatabaseException, that Database is not set in current thread.
Here is a failing test, showing my usage of the API.
import javax.persistence.Id;
import javax.persistence.Version;
import com.orientechnologies.orient.core.db.OPartitionedDatabasePool;
import com.orientechnologies.orient.object.db.OObjectDatabaseTx;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ObjectDatabaseTest {
private MyObjectAuthorRepository repository;
#Before
public void setUp() {
repository = new MyObjectAuthorRepository();
}
#After
public void tearDown() {
repository.close();
}
#Test
public void testAuthor() {
Author savedAuthor = repository.saveAuthor(new Author("Author Name"));
// a detached object also fails when accessing the property
// Assert.assertEquals("Author Name", savedAuthor.getAuthorName());
Author author = repository.findAuthor();
Assert.assertEquals("Author Name", author.getAuthorName());
}
class MyObjectAuthorRepository {
private final OPartitionedDatabasePool pool;
public MyObjectAuthorRepository() {
pool = new OPartitionedDatabasePool("memory:test", "admin", "admin");
pool.setAutoCreate(true);
try (OObjectDatabaseTx db = new OObjectDatabaseTx(pool.acquire())) {
db.setAutomaticSchemaGeneration(true);
db.getEntityManager().registerEntityClass(Author.class);
}
}
private Author saveAuthor(Author author) {
OObjectDatabaseTx db = new OObjectDatabaseTx(pool.acquire());
try {
db.begin();
Author savedAuthor = db.save(author);
db.commit();
return db.detach(savedAuthor);
} catch (Exception ex) {
db.rollback();
throw ex;
} finally {
db.close();
}
}
public Author findAuthor() {
try (OObjectDatabaseTx db = new OObjectDatabaseTx(pool.acquire())) {
return db.browseClass(Author.class).next();
}
}
public void close() {
pool.close();
}
}
#javax.persistence.Entity
public class Author {
#Id
private String id;
#Version
private Long version;
private String authorName;
public Author() {
}
public Author(String authorName) {
this.authorName = authorName;
}
public String getId() {
return id;
}
public Long getVersion() {
return version;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
}
}
Please let me know, if the API should be used in a different way or if any other configuration I'm missing here above. It'll be really helpful. Thanks.
so I have a POJO object that I am creating and saving to a MongoDB collection using Jongo:
import java.util.Map;
public class MyObject {
private String name;
private Map<String, String> mappings;
public MyObject() {
}
public MyObject(String name, Map mappings) {
this.name = name;
this.mappings = mappings;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getMappings() {
return mappings;
}
public void setMappings(Map<String, String> mappings) {
this.mappings = mappings;
}
}
Test class for saving objects to mongo:
import com.mongodb.DB;
import com.mongodb.MongoClient;
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import java.net.UnknownHostException;
import java.util.HashMap;
public class NullFieldTest {
public static void main(String[] args) throws UnknownHostException {
DB db = new MongoClient("localhost", 27017).getDB("testDB") ;
Jongo jongo = new Jongo(db);
MongoCollection testCollection = jongo.getCollection("testCollection");
MyObject objectA = new MyObject("objectA", new HashMap());
MyObject objectB = new MyObject("objectB", null);
testCollection.save(objectA);
testCollection.save(objectB);
}
}
This test saves the objects fine:
{
"_id" : ObjectId("543cf1a6cd8936deafcf66cf"),
"name" : "objectA",
"mappings" : {}
}
{
"_id" : ObjectId("543cf1a6cd8936deafcf66d0"),
"name" : "objectB"
}
but what I really want is for the null mappings in objectB to appear as
"mappings" : null
I know that a field within a collection can have a null value, but I dont know how to do this with the jongo driver, any ideas?
FYI, I'm using jongo V1.1
problem solved, my issue was in the serialization of the objects, added an annotation from Jackson to include even null fields:
#JsonInclude(JsonInclude.Include.ALWAYS)
public class MyObject {
Found more details on this post:
How to tell Jackson to ignore a field during serialization if its value is null?
Jongo comes with a pre-configured Jackson which ignore null fields : https://github.com/bguerout/jongo/blob/443b461e47acdcffb9f51efafb291b7e0c805c26/src/main/java/org/jongo/marshall/jackson/configuration/VisibilityModifier.java
You can change this configuration by creating a custom Mapper using JacksonMapper.Builder :
Mapper mapper = new JacksonMapper.Builder().addModifier(new MapperModifier() {
public void modify(ObjectMapper mapper) {
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
}
}).build();
Jongo jongo = new Jongo(db, mapper);
Say I have the below test case
I want to be able to bind camel case parameters:
anyData.put("my_id", "bob#gmail.com");
How can I get this test to pass??
public class FormBindingExampleTest {
public static class FormBindingExampleModel {
public String myid;
public String email;
public String getMyid() {
return myid;
}
public void setMyid(String myid) {
this.myid = myid;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
#Test
public void itShouldBindForm(){
Form<FormBindingExampleModel> userForm = form(FormBindingExampleModel.class);
Map<String,String> anyData = new HashMap();
anyData.put("my_id", "bob#gmail.com");
anyData.put("email", "secret");
FormBindingExampleModel user = userForm.bind(anyData).get();
System.out.println(user.myid);
assert(user.myid.equals("bob#gmail.com"));
}
}
Use form's fill() method inorder to populate the form with existing value.
#Test
public void itShouldBindForm(){
Form<FormBindingExampleModel> userForm = form(FormBindingExampleModel.class);
FormBindingExampleModel formModel = new FormBindingExampleModel();
formModel.setMyid("bob#gmail.com");
formModel.setEmail("secret");
userForm.fill(formModel);
FormBindingExampleModel user = userForm.get();
System.out.println(user.getMyid);
assert(user.getMyid.equals("bob#gmail.com"));
}
Documentation available here.