readValue() no working with TypeReference - json

I am writing following code to convert my JSON sting to list of my object.
List<MyObject> myResponse = new ArrayList<MyObject>();
myResponse = new ObjectMapper().readValue(responseString, new TypeReference<List<MyObject>>(){});
But eclipse is complaining with following error:
The method readValue(String, Class<T>) in the type ObjectMapper is not applicable for the arguments (String, new TypeReference<List<MyObject>>(){})
What can be possible error?

Issue was with import of TypeReference. I was using
import com.fasterxml.jackson.core.type.TypeReference
instead of
import org.codehaus.jackson.type.TypeReference

For me the issue was with import of ObjectMapper. I was using
import com.fasterxml.jackson.core.type.ObjectMapper
instead of
import org.codehaus.jackson.type.ObjectMapper

Related

RestFul cucumber acceptance test to get local file json as output

I want to mock a resttemplate output. We have a service /someservice/getJson to get json. To mock this service we kept a json file in the code base and tried to get it to the response entity as follows.
working code:
String baseURL = "http://localhost:1010"
String uri = /someservice/getJson
ResponseEntity<T> entity = restTemplate.exchange(baseURL + uri, GET, new HttpEntity<>(headers), type);
I have a json file in the code base (say codebase/../resource/myfile.json)
I would like to get the response entity as the local json I mock.
I tried using exchange method. It doesnt seems as working for me.
What I tried with my json file
String localJson = "/resource/myfile.json";
ResponseEntity<T> entity = restTemplate.exchange(localJson, GET, new HttpEntity<>(headers), type);
I think there are another methods to get it done other than exchange. But I am not aware of those.
Is there any other way / is there any mistake in what I tried ?
To read a file with JSON object and convert it into a POJO you can use ObjectMapper’s
readValue(File src, Class<T> valueType) method (readValue doc link) from Jackson framework:
import java.io.File;
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
YourJsonType response = mapper.readValue( new File("file with JSON object") , YourJsonType.class);

How do I convert a Scala List[org.bson.Document] to a JSON String?

I had a function in AWS Lambda:
def test(pj: Pojo, context: Context): java.util.List[Document]
that was not initializing the pj with the input JSON values at all.
I found another way of doing AWS Lambda in Scala like this:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
val scalaMapper = new ObjectMapper().registerModule(new DefaultScalaModule)
def test(input: InputStream, output: OutputStream): Unit = {
val inputPojo = scalaMapper.readValue(input, classOf[Pojo])
val answer: Seq[Document] = getTheRealAnswer(inputPojo)
val jsonStr = "{ frustration: \"I wish my answer was JSON.\" }"
output.write(jsonStr.getBytes("UTF-8"))
}
and that works, except what I really want to return as an answer is a JSON array of Documents. How should I go about that?
Edit: In my original posting, I wrote: "[the first example] was returning the answer as an error 22. Basically AWS (I think) treated the JSON conversion of the List[Document] as a filename, JSON has plenty of colons, and the error 22 came from colons in filenames not being allowed. Weird." That turned out to be an error in my invocation of the AWS Lambda Function from AWS CLI. I omitted the output filename in the command invocation, and returned JSON was interpreted by AWS CLI as a filename.
Since I wrote this message, I got things to work like this:
def jsonizeDocs(cDocument: Seq[Document]): String = {
val sb=new StringBuilder
for (doc <- cDocument) {
if (sb.nonEmpty) {
sb.append(",")
}
sb.append(doc.toJson)
}
sb.toString
}
Note! This answer is based on a light wrapper I wrote around json4s which I call JSON Extensions
Assuming you are using Scala Objects, import the io.onema.json.Extensions._
import io.onema.json.Extensions._
case class Doc(title: String, content: String)
val listOfDocs = Seq(Doc("Foo", "bar"), Doc("Bar", "Baz"), Doc("Blah", "Bax"))
val json: String = listOfDocs.asJson
println(json)
// [{"title":"Foo","content":"bar"},{"title":"Bar","content":"Baz"},{"title":"Blah","content":"Bax"}]
See the running example here
Now, since you are using a Pojo, you need to import io.onema.json.JavaExtensions._. Assuming you have the following POJO:
public class Document {
private String title;
private String content;
public String getTitle() {return title;}
public String getContent() {return content;}
public void setTitle(String title) { this.title = title;}
public void setContent(String content) {this.content = content;}
}
Use this method in your Scala code like such:
import io.onema.json.JavaExtensions._
import com.example.Document
// ...
def jsonizeDocs(cDocument: Seq[Document]): String = {
val json: String = cDocument.asJson
println(json)
json
}
In AWS Lambda (and to go the other way around) use jsonDecode and a custom object mapper to deserialize to the expected type:
import io.onema.json.JavaExtensions._
import io.onema.json.Mapper
import com.example.Document
val jsonString = """[{"title":"Foo","content":"bar"},{"title":"Bar","content":"Baz"},{"title":"Blah","content":"Bax"}]"""
val mapper: ObjectMapper = Mapper.allowUnknownPropertiesMapper
val doc: Document = jsonString.jsonDecode[Document](mapper)
I have used the method described here quite successfully in a lambda framework that is able to deserialize to AWS lambda events as well as custom types, see a simple example here.
That's it! you can use this library or one of the many JSON serializers in Java or Scala. If you know the type of your objects most libraries will enable you to serialize to JSON and back very easily.

JerseyTest WebTarget POST support

I am developing a light weight server App with a RESTful api implemented with Jersey 2.12 and Jackson 2.
I am writing tests while developing using JUnit and JerseyTest. I know that my Jersey Resources work as expected including the marshalling from and to JSON because I tested them manually with the PostMan Chrome plugin.
My GET tests with query parameters work well too, based on the example in the Jersey documentation
Here is a simplified (I have left out boilerplate code to make the idea clearer) example of a test I'd like to write:
import static org.junit.Assert.assertTrue;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import com.acme.api.rest.SessionsEndPoint;
import com.acme.api.rest.beans.UserCredentialsBean;
public class TestSession extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(SessionsEndPoint.class);
}
#Test
public void test() {
UserCredentialsBean userCredentialsBean = new UserCredentialsBean();
userCredentialsBean.setUserId("alice");
userCredentialsBean.setPassword("secret");
WebTarget theTarget = target("sessions/login");
Response response = theTarget.request().post( Entity.entity(UserCredentialsBean.class, "application/json"));
assertTrue(true);
}
}
The basic problem I have is that I cannot find any documentation on how to properly use the WebTarget class for post requests. the WebTarget theTarget is constructed correctly but the line:
Response response = theTarget.request().post( Entity.entity(UserCredentialsBean.class, "application/json"));
does not work.
As I understand the WebTarget class is fairly new in the JerseyTest framework. Is there anybody who can point me at any recent documentation, examples, or just explain here how I can get this to work?
I did do a lot of googling before I posted my question here, but after checking back my eyes suddenly fell on this Related Question. I did search on SO several times but never found this question. Anyway, here's the solution to my problem:
I started implementing as explained in the accepted answer and got it to work quickly.
Then I decided that you it should be possible to avoid using JSON string representations at all, and I got that to work to.
The code above works if modified as follows:
import static org.junit.Assert.assertTrue;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import com.acme.api.rest.SessionsEndPoint;
import com.acme.api.rest.beans.UserCredentialsBean;
public class TestSession extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(SessionsEndPoint.class);
}
#Test
public void test() {
UserCredentialsBean userCredentialsBean = new UserCredentialsBean();
userCredentialsBean.setUserId("alice");
userCredentialsBean.setPassword("secret");
LoginResponseBean loginResponseBean =
target("sessions/login")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(
Entity.entity(
userCredentialsBean,
MediaType.APPLICATION_JSON_TYPE
),
LoginResponseBean.class
);
assertTrue(
loginResponseBean.isSuccess()
&&
loginResponseBean.getToken().length()==36
);
}
}
LoginResponseBean is a plain Java Bean. Just getters and setters and a default constructor.
Marshalling to- and from JSON is done by the framework, either by moxy or jackson as the JSON provider.

Grails parse JSON into domain class

Hi Say that I have a domain class
class Book{
static hasOne=[author:Author]
long id
String name
}
class Author {
static hasMany=[books:Book]
long id
String name
}
I have a json object sent in. Can I jus do a new Book(Json) and not manually set the property?
Using the built-in Grails JSON converter makes this easier
import grails.converters.JSON
class BookController {
def save = {
def book = new Book(JSON.parse(yourJson))
book.save(flush:true)
}
}
In the code what's happening (we're parsing a JSON object and setting the properties on the Book entity and saving
use the JsonBinder:
def json = request.JSON;
def book= new Book();
JsonBinder.bindJSON(book, json);
dont forget to import these packages:
import grails.converters.JSON;
import com.ocom.grails.JsonBinder;

Serializing and unserializing case classes with lift-json

I'm attempting basic serialization/hydration with lift-json, but without success. As near as I can tell from the package readme, this should work. Help?
I'm using Scala 2.8.0 and Lift 2.2 cross-built for 2.8 with sbt ("net.liftweb" %% "lift-json" % "2.2").
import net.liftweb.json._
import net.liftweb.json.Serialization.{read, write}
implicit val formats = Serialization.formats(NoTypeHints)
case class Route(title: String)
val rt = new Route("x277a1")
val ser = write(rt)
// ser: String = {} ...
val deser = read[Route]("""{"title":"Some Title"}""")
// net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
Lift JSON's serialization does not work for case classes defined in REPL (paranamer can't find the bytecode to read the type metadata). Compile Route with scalac and then the above example works.
The same problem applies every time when the (de)serialuzed class is not on the classpath. In such case, paranamer can't read the parameter names. It is necessary to provide a custom ParameterNameReader.
Such problem applies for e.g.:
REPL (as mentioned) - unless you define the class outside the REPL and add via classpath.
Play Framework - unless you provide a simple custom ParameterNameReader (see below) or load the (de)serialized class as a Maven/Play/... dependency
Feel free to add another situation (you can edit this post).
The PlayParameterNameReader:
import net.liftweb.json.ParameterNameReader
import java.lang.reflect.Constructor
import play.classloading.enhancers.LocalvariablesNamesEnhancer
import scala.collection.JavaConversions._
object PlayParameterReader extends ParameterNameReader{
def lookupParameterNames(constructor: Constructor[_]) = LocalvariablesNamesEnhancer.lookupParameterNames(constructor)
}