Spring JSON Jackson Marshaller adding additional parameter in my response object - json

This is one of the strangest errors I have encountered in a long time.
I have a ServerResponse POJO that I respond with from my Spring MVC REST app using JSON or XML Marshaller configured with ContentNegotiatingViewResolver.
Now my standard JSON response in case of error should look like ->
{ response: { result: null, error: {code: "500", message: "Internal Server Error"}}
and a similar XML.
Instead I'm getting the following in case a Hibernate exception occurs in:
{
"response": {
"result": null,
"error": {
"message": "Internal Server Error",
"code": "500"
},
"respTime": "100 ms"
},
"exception": {
"cause": null,
"message": null,
"localizedMessage": null,
"stackTrace": [(45)
{
"fileName": "NativeConstructorAccessorImpl.java",
"lineNumber": -2,
"className": "sun.reflect.NativeConstructorAccessorImpl",
"methodName": "newInstance0",
"nativeMethod": true
},
{
"fileName": "NativeConstructorAccessorImpl.java",
"lineNumber": 39,
"className": "sun.reflect.NativeConstructorAccessorImpl",
"methodName": "newInstance",
"nativeMethod": false
},
{
"fileName": "DelegatingConstructorAccessorImpl.java",
"lineNumber": 27,
"className": "sun.reflect.DelegatingConstructorAccessorImpl",
"methodName": "newInstance",
"nativeMethod": false
},
{
"fileName": "Constructor.java",
"lineNumber": 513,
"className": "java.lang.reflect.Constructor",
"methodName": "newInstance",
"nativeMethod": false
},
{
"fileName": "BeanUtils.java",
"lineNumber": 147,
"className": "org.springframework.beans.BeanUtils",
"methodName": "instantiateClass",
"nativeMethod": false
},
{
"fileName": "BeanUtils.java",
"lineNumber": 104,
"className": "org.springframework.beans.BeanUtils",
"methodName": "instantiateClass",
"nativeMethod": false
},
{
"fileName": "ModelAttributeMethodProcessor.java",
"lineNumber": 125,
"className": "org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor",
"methodName": "createDataBinder",
"nativeMethod": false
},
{
"fileName": "ModelAttributeMethodProcessor.java",
"lineNumber": 92,
"className": "org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor",
"methodName": "resolveArgument",
"nativeMethod": false
},
{
"fileName": "HandlerMethodArgumentResolverComposite.java",
"lineNumber": 65,
"className": "org.springframework.web.method.support.HandlerMethodArgumentResolverComposite",
"methodName": "resolveArgument",
"nativeMethod": false
},
{
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 153,
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"methodName": "getMethodArgumentValues",
"nativeMethod": false
},
{
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 117,
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"methodName": "invokeForRequest",
"nativeMethod": false
},
{
"fileName": "ModelFactory.java",
"lineNumber": 118,
"className": "org.springframework.web.method.annotation.ModelFactory",
"methodName": "invokeAttributeMethods",
"nativeMethod": false
},
{
"fileName": "ModelFactory.java",
"lineNumber": 100,
"className": "org.springframework.web.method.annotation.ModelFactory",
"methodName": "initModel",
"nativeMethod": false
},
{
"fileName": "RequestMappingHandlerAdapter.java",
"lineNumber": 500,
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter",
"methodName": "invokeHandlerMethod",
"nativeMethod": false
},
{
"fileName": "RequestMappingHandlerAdapter.java",
"lineNumber": 465,
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter",
"methodName": "handleInternal",
"nativeMethod": false
},
{
"fileName": "AbstractHandlerMethodAdapter.java",
"lineNumber": 80,
"className": "org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter",
"methodName": "handle",
"nativeMethod": false
},
{
"fileName": "DispatcherServlet.java",
"lineNumber": 863,
"className": "org.springframework.web.servlet.DispatcherServlet",
"methodName": "doDispatch",
"nativeMethod": false
},
{
"fileName": "BaseDispatcherServlet.java",
"lineNumber": 31,
"className": "com.locationguru.framework.base.BaseDispatcherServlet",
"methodName": "doDispatch",
"nativeMethod": false
},
{
"fileName": "DispatcherServlet.java",
"lineNumber": 792,
"className": "org.springframework.web.servlet.DispatcherServlet",
"methodName": "doService",
"nativeMethod": false
},
{
"fileName": "BaseDispatcherServlet.java",
"lineNumber": 24,
"className": "com.locationguru.framework.base.BaseDispatcherServlet",
"methodName": "doService",
"nativeMethod": false
},
{
"fileName": "FrameworkServlet.java",
"lineNumber": 851,
"className": "org.springframework.web.servlet.FrameworkServlet",
"methodName": "processRequest",
"nativeMethod": false
},
{
"fileName": "FrameworkServlet.java",
"lineNumber": 767,
"className": "org.springframework.web.servlet.FrameworkServlet",
"methodName": "doPost",
"nativeMethod": false
},
{
"fileName": "HttpServlet.java",
"lineNumber": 641,
"className": "javax.servlet.http.HttpServlet",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "BaseDispatcherServlet.java",
"lineNumber": 38,
"className": "com.locationguru.framework.base.BaseDispatcherServlet",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "HttpServlet.java",
"lineNumber": 722,
"className": "javax.servlet.http.HttpServlet",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "ApplicationFilterChain.java",
"lineNumber": 304,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"fileName": "ApplicationFilterChain.java",
"lineNumber": 210,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"methodName": "doFilter",
"nativeMethod": false
},
{
"fileName": "OpenSessionInViewFilter.java",
"lineNumber": 198,
"className": "org.springframework.orm.hibernate3.support.OpenSessionInViewFilter",
"methodName": "doFilterInternal",
"nativeMethod": false
},
{
"fileName": "OncePerRequestFilter.java",
"lineNumber": 76,
"className": "org.springframework.web.filter.OncePerRequestFilter",
"methodName": "doFilter",
"nativeMethod": false
},
{
"fileName": "ApplicationFilterChain.java",
"lineNumber": 243,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"fileName": "ApplicationFilterChain.java",
"lineNumber": 210,
"className": "org.apache.catalina.core.ApplicationFilterChain",
"methodName": "doFilter",
"nativeMethod": false
},
{
"fileName": "StandardWrapperValve.java",
"lineNumber": 224,
"className": "org.apache.catalina.core.StandardWrapperValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "StandardContextValve.java",
"lineNumber": 185,
"className": "org.apache.catalina.core.StandardContextValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "AuthenticatorBase.java",
"lineNumber": 472,
"className": "org.apache.catalina.authenticator.AuthenticatorBase",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "StandardHostValve.java",
"lineNumber": 151,
"className": "org.apache.catalina.core.StandardHostValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "ErrorReportValve.java",
"lineNumber": 100,
"className": "org.apache.catalina.valves.ErrorReportValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "AccessLogValve.java",
"lineNumber": 929,
"className": "org.apache.catalina.valves.AccessLogValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "StandardEngineValve.java",
"lineNumber": 118,
"className": "org.apache.catalina.core.StandardEngineValve",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "CoyoteAdapter.java",
"lineNumber": 405,
"className": "org.apache.catalina.connector.CoyoteAdapter",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "Http11Processor.java",
"lineNumber": 269,
"className": "org.apache.coyote.http11.Http11Processor",
"methodName": "process",
"nativeMethod": false
},
{
"fileName": "AbstractProtocol.java",
"lineNumber": 515,
"className": "org.apache.coyote.AbstractProtocol$AbstractConnectionHandler",
"methodName": "process",
"nativeMethod": false
},
{
"fileName": "JIoEndpoint.java",
"lineNumber": 300,
"className": "org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 886,
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"methodName": "runTask",
"nativeMethod": false
},
{
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 908,
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "Thread.java",
"lineNumber": 680,
"className": "java.lang.Thread",
"methodName": "run",
"nativeMethod": false
}
]
}
}
While the XML is still coming out correctly.
Any Ideas?

The following configuration while Jackson Json Marshaller bean helped remove the unncessary keys getting rendered in my JSON response.
<!-- XStream XML View -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="autodetectAnnotations" value="true"/>
<property name="annotatedClasses">
<list>
<value>framework.response.object.ServerResponse</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
<property name="defaultContentType" value="application/xml"/>
<property name="favorPathExtension" value="true"/>
</bean>
Focus Here -->
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="modelKey" value="response" />
</bean>

Related

Problem getting Image URL with Strapi / Nuxt

I am trying to get the image URL from a JSON which I get from a call to my strapi content. It is for an events website. Here is the code. When I console.log the image url, i get 'undefined'. However, all other properties of event show up no problem.
created() {
axios.get('http://localhost:1338/events').then(res => {
this.events = res.data.sort((a, b) => b.date < a.date ? 1: -1);
console.log(this.events[0].image.url)
})
.catch(err => console.log(err))
}
Console: undefined
Here is the JSON:
{
"id": 1,
"title": "Aphex Twin Live Set",
"description": "Risus viverra adipiscing at in tellus integer feugiat scelerisque varius.",
"date": "2020-12-23T16:00:00.000Z",
"price": 10,
"published_at": "2020-12-19T17:25:44.340Z",
"created_at": "2020-12-19T17:25:41.833Z",
"updated_at": "2020-12-19T21:42:15.696Z",
"image": [
{
"id": 1,
"name": "aphex.jpeg",
"alternativeText": "",
"caption": "",
"width": 1200,
"height": 630,
"formats": {
"thumbnail": {
"name": "thumbnail_aphex.jpeg",
"hash": "thumbnail_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 245,
"height": 129,
"size": 4.12,
"path": null,
"url": "/uploads/thumbnail_aphex_11b34d4058.jpeg"
},
"large": {
"name": "large_aphex.jpeg",
"hash": "large_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 1000,
"height": 525,
"size": 28.49,
"path": null,
"url": "/uploads/large_aphex_11b34d4058.jpeg"
},
"medium": {
"name": "medium_aphex.jpeg",
"hash": "medium_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 750,
"height": 394,
"size": 18.95,
"path": null,
"url": "/uploads/medium_aphex_11b34d4058.jpeg"
},
"small": {
"name": "small_aphex.jpeg",
"hash": "small_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 500,
"height": 263,
"size": 10.67,
"path": null,
"url": "/uploads/small_aphex_11b34d4058.jpeg"
}
},
"hash": "aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"size": 37.07,
"url": "/uploads/aphex_11b34d4058.jpeg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2020-12-19T17:25:35.172Z",
"updated_at": "2020-12-19T17:25:35.183Z"
}
],
"categories": [
{
"id": 1,
"name": "Music",
"published_at": "2020-12-19T21:18:16.946Z",
"created_at": "2020-12-19T21:18:13.393Z",
"updated_at": "2020-12-19T21:18:16.961Z"
}
],
"artists": [
{
"id": 1,
"name": "Aphex Twin",
"bio": "Richard James is a pretty old guy by now but he was banging in the techno/ambient electronic scene in the late 80s and 90s. He's from Cornwall so must've been pretty bored on most days, which lead him to hack at computers and electronic sound generators. The rest is history.",
"published_at": "2020-12-19T21:42:33.225Z",
"created_at": "2020-12-19T21:42:03.445Z",
"updated_at": "2020-12-19T21:42:33.251Z",
"artist_image": []
}
]
}
Again -- all fields show if I console.log, but not image.url
Got it -- the image field is an array because I allowed multiple media on Strapi. Had to do event.image[0].url

Ionic Json nested

I'm new in Ionic development. I'm having a problem retrieving JSON.
"Failed to load https://api.wh.geniussports.com/v1/basketball/competitions/19816/matcheslive?ak=eebd8ae256142ac3fd24bd2003d28782: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access."
Here's my json format
{
"response": {
"meta": {
"version": 1,
"code": 200,
"status": "success",
"request": "http://api.wh.geniussports.com/v1/basketball/competitions/19816/matcheslive?ak=eebd8ae256142ac3fd24bd2003d28782",
"time": 1528177532,
"count": 10,
"limit": 10
},
"data": [
{
"leagueId": 6,
"matchId": 784470,
"competitionId": 19816,
"venueId": 17386,
"poolNumber": 0,
"roundNumber": "1",
"roundDescription": "",
"matchNumber": 1,
"matchStatus": "COMPLETE",
"matchName": "",
"phaseName": "",
"extraPeriodsUsed": 0,
"matchTime": "2017-11-17 19:30:00",
"matchTimeUTC": "2017-11-17 11:30:00",
"enddate": null,
"timeActual": "2017-11-17 19:45:37",
"timeEndActual": "2017-11-17 21:12:10",
"durationActual": 87,
"temperature": 0,
"attendance": 0,
"duration": 120,
"weather": "",
"twitterHashtag": "",
"liveStream": 1,
"matchType": "REGULAR",
"keywords": "",
"ticketURL": "",
"externalId": "920",
"nextMatchId": 0,
"placeIfWon": 0,
"placeIfLost": 0,
"updated": "2017-11-24 11:04:00",
"linkDetail": "/v1/basketball/matches/784470",
"linkDetailLeague": "/v1/basketball/leagues/6",
"venue": {
"venueId": 17386,
"venueName": "Nanhai Gymnasium",
"venueNameInternational": "",
"venueNickname": "Nanhai Gym",
"venueNicknameInternational": "",
"surfaceName": "",
"locationName": "",
"website": "",
"ticketURL": "",
"externalId": "54",
"linkDetailVenue": "/v1/basketball/venues/17386"
},
"leagueName": "ASEAN Basketball League",
"leagueNameInternational": "",
"competitionName": "2017 ASEAN Basketball League",
"competitionNameInternational": "",
"gsId": "",
"competitors": [
{
"competitorType": "TEAM",
"competitorName": "Singapore Slingers",
"competitorId": 88261,
"linkDetailCompetitor": "/v1/basketball/teams/88261",
"scoreString": "59",
"scoreSecondaryString": "",
"completionStatus": "COMPLETE",
"resultPlacing": 0,
"isDrawn": 0,
"isHomeCompetitor": 0,
"teamId": 88261,
"teamName": "Singapore Slingers",
"teamGsId": null,
"teamNameInternational": "",
"teamNickname": "Singapore Slingers",
"teamNicknameInternational": "",
"teamCode": "",
"teamCodeInternational": "",
"website": "",
"internationalReference": "",
"externalId": "74",
"images": {
"logo": {
"L1": {
"size": "L1",
"height": 600,
"width": 600,
"bytes": 45196,
"url": "http://img.wh.sportingpulseinternational.com/5b71cf0a1af51c8376eda43e6ba5bc22L1.jpg"
},
"M1": {
"size": "M1",
"height": 400,
"width": 400,
"bytes": 25005,
"url": "http://img.wh.sportingpulseinternational.com/5b71cf0a1af51c8376eda43e6ba5bc22M1.jpg"
},
"S1": {
"size": "S1",
"height": 200,
"width": 200,
"bytes": 9180,
"url": "http://img.wh.sportingpulseinternational.com/5b71cf0a1af51c8376eda43e6ba5bc22S1.jpg"
},
"T1": {
"size": "T1",
"height": 75,
"width": 75,
"bytes": 2270,
"url": "http://img.wh.sportingpulseinternational.com/5b71cf0a1af51c8376eda43e6ba5bc22T1.jpg"
}
}
},
"clubId": 62,
"clubGsId": null,
"clubName": "Singapore Slingers",
"clubNameInternational": "",
"linkDetailClub": "/v1/basketball/clubs/62"
},
Below is my loadUser function
loadUser(){
this.http.get('http://api.wh.geniussports.com/v1/basketball/competitions/19816/matcheslive?ak=eebd8ae256142ac3fd24bd2003d28782')
.map(res => res.json())
.subscribe(res => {
this.data = data.results;
console.log(data.results);
}, err => {
console.log(err);
});
}
My main goal is to log the data[] array. Please help me
This is the problem with browser, typically its a security concern not to allow other requests which may lead to XSS attack easily. If only for development I suggest you to install a plugin which will disable in your browser plugin
If for production, then you need to configure your API then do this .

Cannot read JSON in pandas

I have a nested JSON. I want it to be read in pandas in order to explore it, but I got errors. When to use read_json method, I got: "Trailing data". It is valid JSON. How to read it in pd? (Tried differently, but did not work). It looks like this:
{
"contributors": null,
"coordinates": null,
"created_at": "Fri May 26 08:54:00 +0000 2017",
"entities": {
"hashtags": [],
"media": [
{
"display_url": "pic.twitter.com/Pm28ORTePl",
"expanded_url": "",
"id": 868027417121751040,
"id_str": "868027417121751040",
"indices": [
94,
117
],
"media_url": "",
"sizes": {
"large": {
"h": 404,
"resize": "fit",
"w": 773
},
"medium": {
"h": 404,
"resize": "fit",
"w": 773
},
"small": {
"h": 355,
"resize": "fit",
"w": 680
},
"thumb": {
"h": 150,
"resize": "crop",
"w": 150
}
},
"type": "photo",
"url": ""
}
],
"symbols": [],
"urls": [
{
"display_url": "",
"expanded_url": "",
"indices": [
70,
93
],
"url": ""
}
],
"user_mentions": []
},
"extended_entities": {
"media": [
{
"display_url": "pic.twitter.com/Pm28ORTePl",
"expanded_url": "1",
"id": 868027417121751040,
"id_str": "868027417121751040",
"indices": [
94,
117
],
"media_url": "",
"media_url_https": "",
"sizes": {
"large": {
"h": 404,
"resize": "fit",
"w": 773
},
"medium": {
"h": 404,
"resize": "fit",
"w": 773
},
"small": {
"h": 355,
"resize": "fit",
"w": 680
},
"thumb": {
"h": 150,
"resize": "crop",
"w": 150
}
},
"type": "photo",
"url": ""
}
]
},
"favorite_count": 1,
"favorited": false,
"geo": null,
"id": 868027425757724672,
"id_str": "868027425757724672",
"in_reply_to_screen_name": null,
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"is_quote_status": false,
"lang": "ru",
"place": null,
"possibly_sensitive": false,
"retweet_count": 0,
"retweeted": false,
"source": "Twitter Web Client",
"text": "\u041f\u0440\u043e\u043f\u0430\u0432\u0448\u0430\u044f \u0432 \u041a\u043e\u043a\u0448\u0435\u0442\u0430\u0443 \u0448\u043a\u043e\u043b\u044c\u043d\u0438\u0446\u0430 \u0436\u0438\u043b\u0430 \u0432 \u0437\u0430\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u043c \u0434\u043e\u043c\u0435 \u0438 \u0431\u0440\u043e\u0434\u044f\u0436\u043d\u0438\u0447\u0430\u043b\u0430\n",
"truncated": false,
"user": {
"contributors_enabled": false,
"created_at": "Wed May 18 11:59:50 +0000 2011",
"default_profile": true,
"default_profile_image": false,
"description": "\u041a\u0430\u0437\u0430\u0445\u0441\u0442\u0430\u043d\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043f\u043e\u0440\u0442\u0430\u043b",
"entities": {
"description": {
"urls": []
},
"url": {
"urls": [
{
"display_url": "",
"expanded_url": "",
"indices": [
0,
22
],
"url": ""
}
]
}
},
"favourites_count": 87,
"follow_request_sent": false,
"followers_count": 17989,
"following": true,
"friends_count": 98,
"geo_enabled": true,
"has_extended_profile": false,
"id": 300811189,
"id_str": "300811189",
"is_translation_enabled": false,
"is_translator": false,
"lang": "ru",
"listed_count": 86,
"location": "\u0410\u043b\u043c\u0430\u0442\u044b",
"name": "",
"notifications": false,
"profile_background_color": "C0DEED",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": false,
"profile_banner_url": "https://pbs.twimg.com/profile_banners/300811189/1489117916",
"profile_image_url": "http://pbs.twimg.com/profile_images/840047424882298881/NxZSyfhM_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/840047424882298881/NxZSyfhM_normal.jpg",
"profile_link_color": "1DA1F2",
"profile_sidebar_border_color": "C0DEED",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"protected": false,
"screen_name": "",
"statuses_count": 53011,
"time_zone": "Quito",
"translator_type": "none",
"url": "",
"utc_offset": -18000,
"verified": false
}
}
Sorry, but your JSON is actually not valid, despite your saying it is.
This line:
"media_url": "": "",
Should probably be:
"media_url": "",
At which point, when I added the final bracket } that was outside of your code block, validated as properly formed JSON.

How to prevent JAX.RS ExceptionMapper including the stacktrace

I have the following code in my JAX.RS ExceptionMapper:
#Override
public Response toResponse(ResponseStatusCodeException ex) {
ResponseStatusCode newEx = new ResponseStatusCode(ex);
return Response.status(ex.getStatus()).entity(newEx).type(MediaType.APPLICATION_JSON).build();
}
This generates a JSON response that includes a full exception stack trace starting in the Response.status() line.
How can I make the ExceptionMapper just to return the JSON encoded properties for the newEx class. I have even tried making ResponseStatusCode a POJO not extending Exception but the stack trace is always included in the response.
I am using Websphere Liberty profile 8.5.5.8.
Thanks
Edited: Let me add the JSON generated:
{
"message": "Language en is not currently available",
"status": 500,
"username": "901353fa-b43e-4e86-b12f-6d502a9e8a78",
"localizedMessage": "Language en is not currently available",
"stackTrace": [
{
"fileName": "ResponseStatusCodeExceptionHandler.java",
"lineNumber": 14,
"className": "com.servengine.ws.rs.ResponseStatusCodeExceptionHandler",
"methodName": "toResponse",
"nativeMethod": false
},
{
"fileName": "ResponseStatusCodeExceptionHandler.java",
"lineNumber": 1,
"className": "com.servengine.ws.rs.ResponseStatusCodeExceptionHandler",
"methodName": "toResponse",
"nativeMethod": false
},
{
"fileName": "ExceptionUtils.java",
"lineNumber": 90,
"className": "org.apache.cxf.jaxrs.utils.ExceptionUtils",
"methodName": "convertFaultToResponse",
"nativeMethod": false
},
{
"fileName": "JAXRSUtils.java",
"lineNumber": 1621,
"className": "org.apache.cxf.jaxrs.utils.JAXRSUtils",
"methodName": "convertFaultToResponse",
"nativeMethod": false
},
{
"fileName": "JAXRSInvoker.java",
"lineNumber": 324,
"className": "org.apache.cxf.jaxrs.JAXRSInvoker",
"methodName": "handleFault",
"nativeMethod": false
},
{
"fileName": "JAXRSInvoker.java",
"lineNumber": 213,
"className": "org.apache.cxf.jaxrs.JAXRSInvoker",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "LibertyJaxRsInvoker.java",
"lineNumber": 366,
"className": "com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "JAXRSInvoker.java",
"lineNumber": 99,
"className": "org.apache.cxf.jaxrs.JAXRSInvoker",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "ServiceInvokerInterceptor.java",
"lineNumber": 59,
"className": "org.apache.cxf.interceptor.ServiceInvokerInterceptor$1",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "ServiceInvokerInterceptor.java",
"lineNumber": 96,
"className": "org.apache.cxf.interceptor.ServiceInvokerInterceptor",
"methodName": "handleMessage",
"nativeMethod": false
},
{
"fileName": "PhaseInterceptorChain.java",
"lineNumber": 307,
"className": "org.apache.cxf.phase.PhaseInterceptorChain",
"methodName": "doIntercept",
"nativeMethod": false
},
{
"fileName": "ChainInitiationObserver.java",
"lineNumber": 124,
"className": "org.apache.cxf.transport.ChainInitiationObserver",
"methodName": "onMessage",
"nativeMethod": false
},
{
"fileName": "AbstractHTTPDestination.java",
"lineNumber": 256,
"className": "org.apache.cxf.transport.http.AbstractHTTPDestination",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "AbstractJaxRsWebEndpoint.java",
"lineNumber": 134,
"className": "com.ibm.ws.jaxrs20.endpoint.AbstractJaxRsWebEndpoint",
"methodName": "invoke",
"nativeMethod": false
},
{
"fileName": "IBMRestServlet.java",
"lineNumber": 149,
"className": "com.ibm.websphere.jaxrs.server.IBMRestServlet",
"methodName": "handleRequest",
"nativeMethod": false
},
{
"fileName": "IBMRestServlet.java",
"lineNumber": 107,
"className": "com.ibm.websphere.jaxrs.server.IBMRestServlet",
"methodName": "doPost",
"nativeMethod": false
},
{
"fileName": "HttpServlet.java",
"lineNumber": 707,
"className": "javax.servlet.http.HttpServlet",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "IBMRestServlet.java",
"lineNumber": 99,
"className": "com.ibm.websphere.jaxrs.server.IBMRestServlet",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "ServletWrapper.java",
"lineNumber": 1287,
"className": "com.ibm.ws.webcontainer.servlet.ServletWrapper",
"methodName": "service",
"nativeMethod": false
},
{
"fileName": "ServletWrapper.java",
"lineNumber": 778,
"className": "com.ibm.ws.webcontainer.servlet.ServletWrapper",
"methodName": "handleRequest",
"nativeMethod": false
},
{
"fileName": "ServletWrapper.java",
"lineNumber": 475,
"className": "com.ibm.ws.webcontainer.servlet.ServletWrapper",
"methodName": "handleRequest",
"nativeMethod": false
},
{
"fileName": "WebAppFilterChain.java",
"lineNumber": 146,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterChain",
"methodName": "invokeTarget",
"nativeMethod": false
},
{
"fileName": "WebAppFilterChain.java",
"lineNumber": 78,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterChain",
"methodName": "doFilter",
"nativeMethod": false
},
{
"fileName": "WebAppFilterManager.java",
"lineNumber": 1020,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterManager",
"methodName": "doFilter",
"nativeMethod": false
},
{
"fileName": "WebAppFilterManager.java",
"lineNumber": 1142,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterManager",
"methodName": "invokeFilters",
"nativeMethod": false
},
{
"fileName": "CacheServletWrapper.java",
"lineNumber": 81,
"className": "com.ibm.ws.webcontainer.servlet.CacheServletWrapper",
"methodName": "__handleRequest",
"nativeMethod": false
},
{
"fileName": "CacheServletWrapper.java",
"lineNumber": -1,
"className": "com.ibm.ws.webcontainer.servlet.CacheServletWrapper",
"methodName": "handleRequest",
"nativeMethod": false
},
{
"fileName": "WebContainer.java",
"lineNumber": 928,
"className": "com.ibm.ws.webcontainer.WebContainer",
"methodName": "handleRequest",
"nativeMethod": false
},
{
"fileName": "DynamicVirtualHost.java",
"lineNumber": 262,
"className": "com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "HttpDispatcherLink.java",
"lineNumber": 955,
"className": "com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "HttpDispatcherLink.java",
"lineNumber": 341,
"className": "com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink",
"methodName": "ready",
"nativeMethod": false
},
{
"fileName": "HttpInboundLink.java",
"lineNumber": 470,
"className": "com.ibm.ws.http.channel.internal.inbound.HttpInboundLink",
"methodName": "handleDiscrimination",
"nativeMethod": false
},
{
"fileName": "HttpInboundLink.java",
"lineNumber": 404,
"className": "com.ibm.ws.http.channel.internal.inbound.HttpInboundLink",
"methodName": "handleNewRequest",
"nativeMethod": false
},
{
"fileName": "HttpInboundLink.java",
"lineNumber": 284,
"className": "com.ibm.ws.http.channel.internal.inbound.HttpInboundLink",
"methodName": "processRequest",
"nativeMethod": false
},
{
"fileName": "HttpInboundLink.java",
"lineNumber": 255,
"className": "com.ibm.ws.http.channel.internal.inbound.HttpInboundLink",
"methodName": "ready",
"nativeMethod": false
},
{
"fileName": "NewConnectionInitialReadCallback.java",
"lineNumber": 174,
"className": "com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback",
"methodName": "sendToDiscriminators",
"nativeMethod": false
},
{
"fileName": "NewConnectionInitialReadCallback.java",
"lineNumber": 83,
"className": "com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback",
"methodName": "complete",
"nativeMethod": false
},
{
"fileName": "WorkQueueManager.java",
"lineNumber": 504,
"className": "com.ibm.ws.tcpchannel.internal.WorkQueueManager",
"methodName": "requestComplete",
"nativeMethod": false
},
{
"fileName": "WorkQueueManager.java",
"lineNumber": 574,
"className": "com.ibm.ws.tcpchannel.internal.WorkQueueManager",
"methodName": "attemptIO",
"nativeMethod": false
},
{
"fileName": "WorkQueueManager.java",
"lineNumber": 929,
"className": "com.ibm.ws.tcpchannel.internal.WorkQueueManager",
"methodName": "workerRun",
"nativeMethod": false
},
{
"fileName": "WorkQueueManager.java",
"lineNumber": 1018,
"className": "com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 1142,
"className": "java.util.concurrent.ThreadPoolExecutor",
"methodName": "runWorker",
"nativeMethod": false
},
{
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 617,
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"methodName": "run",
"nativeMethod": false
},
{
"fileName": "Thread.java",
"lineNumber": 745,
"className": "java.lang.Thread",
"methodName": "run",
"nativeMethod": false
}
],
"suppressed": [
]
}
And the POJO:
package com.servengine.ws.rs;
public class ResponseStatusCode extends Exception {
private static final long serialVersionUID = 1L;
private int status;
private String message, username, code;
public ResponseStatusCode(ResponseStatusCodeException exception) {
this.message = exception.getMessage();
this.username = exception.getUsername();
this.code = exception.getCode();
this.status = exception.getStatus();
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
If the class to be marshalled to JSON extends Exception, a stack trace will be included. I changed it to Serializable, which I had not done yet, and no stack trace is included.
Many thanks to #peeskillet for his replies.
If you are using jackson to marshal POJO to JSON, you may try this:
#JsonIgnoreProperties(value = "stackTrace")
public class ResponseStatusCode extends Exception

parsing a large multi nested json into scala case class

Below is a json example of Twitter's tweet. It's a large json. What is the best library/method to parse it into a case class in scala?
For instance, in Play Framework 2.x it's possible to do that with it's internal library by defining case classes and implicit conversions, but in this case I don't use Play. Should I?
spray-json seems to be most popular scala json library, but in this case it looks quite disappointing - standard approach seems to be limited to 22 elements and uses pattern matching, which becomes ridiculous in the context of multi nested structure with hundreds of elements. Any ideas?
{
"created_at": "Sat Oct 24 06:44:34 +0000 2015",
"id": 657809891558576132,
"id_str": "657809891558576132",
"text": "RT #M23projects: Kara Walker \"Go to Hell or Atlanta, Whichever Come First\" #victoriamiro #London https://t.co/HapqKa4i0l https://t.co/95G…",
"source": "Twitter for iPhone",
"truncated": false,
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 2792146884,
"id_str": "2792146884",
"name": "Tonbridge School Art",
"screen_name": "ArtTonSchool",
"location": "Tonbridge",
"url": null,
"description": "Tonbridge School is an independent day and boarding school for boys. Tweets by the Art Department.",
"protected": false,
"verified": false,
"followers_count": 187,
"friends_count": 288,
"listed_count": 10,
"favourites_count": 1069,
"statuses_count": 1764,
"created_at": "Fri Sep 05 15:37:43 +0000 2014",
"utc_offset": 3600,
"time_zone": "London",
"geo_enabled": true,
"lang": "en-gb",
"contributors_enabled": false,
"is_translator": false,
"profile_background_color": "C0DEED",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": false,
"profile_link_color": "0084B4",
"profile_sidebar_border_color": "C0DEED",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"profile_image_url": "http://pbs.twimg.com/profile_images/507921409738543104/V35eZACR_normal.jpeg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/507921409738543104/V35eZACR_normal.jpeg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/2792146884/1410119421",
"default_profile": true,
"default_profile_image": false,
"following": null,
"follow_request_sent": null,
"notifications": null
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"retweeted_status": {
"created_at": "Sat Oct 24 02:27:06 +0000 2015",
"id": 657745100739506176,
"id_str": "657745100739506176",
"text": "Kara Walker \"Go to Hell or Atlanta, Whichever Come First\" #victoriamiro #London https://t.co/HapqKa4i0l https://t.co/95GaLC4XTo",
"source": "Twitter for iPhone",
"truncated": false,
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 999716342,
"id_str": "999716342",
"name": "M23",
"screen_name": "M23projects",
"location": "New York",
"url": "http://M23.co",
"description": "M23's project space + itinerant program promotes new work by new artists. \nhttp://Instagram.com/m23projects",
"protected": false,
"verified": false,
"followers_count": 9150,
"friends_count": 7353,
"listed_count": 174,
"favourites_count": 1354,
"statuses_count": 4666,
"created_at": "Sun Dec 09 17:13:35 +0000 2012",
"utc_offset": -14400,
"time_zone": "Eastern Time (US & Canada)",
"geo_enabled": true,
"lang": "en",
"contributors_enabled": false,
"is_translator": false,
"profile_background_color": "547587",
"profile_background_image_url": "http://pbs.twimg.com/profile_background_images/884257252/e329bbc1b91d695862d5b23a209f2d34.jpeg",
"profile_background_image_url_https": "https://pbs.twimg.com/profile_background_images/884257252/e329bbc1b91d695862d5b23a209f2d34.jpeg",
"profile_background_tile": true,
"profile_link_color": "414A4D",
"profile_sidebar_border_color": "FFFFFF",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"profile_image_url": "http://pbs.twimg.com/profile_images/458985956830236673/Z_4Bq9PJ_normal.jpeg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/458985956830236673/Z_4Bq9PJ_normal.jpeg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/999716342/1398650659",
"default_profile": false,
"default_profile_image": false,
"following": null,
"follow_request_sent": null,
"notifications": null
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"is_quote_status": false,
"retweet_count": 2,
"favorite_count": 3,
"entities": {
"hashtags": [
{
"text": "London",
"indices": [
74,
81
]
}
],
"urls": [
{
"url": "https://t.co/HapqKa4i0l",
"expanded_url": "http://instagram.com/m23projects",
"display_url": "instagram.com/m23projects",
"indices": [
82,
105
]
}
],
"user_mentions": [
{
"screen_name": "victoriamiro",
"name": "Victoria Miro",
"id": 373924746,
"id_str": "373924746",
"indices": [
58,
71
]
}
],
"symbols": [],
"media": [
{
"id": 657745078413201408,
"id_str": "657745078413201408",
"indices": [
106,
129
],
"media_url": "http://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
}
}
]
},
"extended_entities": {
"media": [
{
"id": 657745078413201408,
"id_str": "657745078413201408",
"indices": [
106,
129
],
"media_url": "http://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
}
},
{
"id": 657745085275095040,
"id_str": "657745085275095040",
"indices": [
106,
129
],
"media_url": "http://pbs.twimg.com/media/CSDHq5CUwAAC-6a.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5CUwAAC-6a.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 453,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 800,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 768,
"h": 1024,
"resize": "fit"
}
}
},
{
"id": 657745085300277248,
"id_str": "657745085300277248",
"indices": [
106,
129
],
"media_url": "http://pbs.twimg.com/media/CSDHq5IVAAAn2YH.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5IVAAAn2YH.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 453,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 800,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 768,
"h": 1024,
"resize": "fit"
}
}
},
{
"id": 657745085275082752,
"id_str": "657745085275082752",
"indices": [
106,
129
],
"media_url": "http://pbs.twimg.com/media/CSDHq5CUkAAd0oL.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5CUkAAd0oL.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
}
}
]
},
"favorited": false,
"retweeted": false,
"possibly_sensitive": false,
"filter_level": "low",
"lang": "en"
},
"is_quote_status": false,
"retweet_count": 0,
"favorite_count": 0,
"entities": {
"hashtags": [
{
"text": "London",
"indices": [
91,
98
]
}
],
"urls": [
{
"url": "https://t.co/HapqKa4i0l",
"expanded_url": "http://instagram.com/m23projects",
"display_url": "instagram.com/m23projects",
"indices": [
99,
122
]
}
],
"user_mentions": [
{
"screen_name": "M23projects",
"name": "M23",
"id": 999716342,
"id_str": "999716342",
"indices": [
3,
15
]
},
{
"screen_name": "victoriamiro",
"name": "Victoria Miro",
"id": 373924746,
"id_str": "373924746",
"indices": [
75,
88
]
}
],
"symbols": [],
"media": [
{
"id": 657745078413201408,
"id_str": "657745078413201408",
"indices": [
123,
140
],
"media_url": "http://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
},
"source_status_id": 657745100739506176,
"source_status_id_str": "657745100739506176",
"source_user_id": 999716342,
"source_user_id_str": "999716342"
}
]
},
"extended_entities": {
"media": [
{
"id": 657745078413201408,
"id_str": "657745078413201408",
"indices": [
123,
140
],
"media_url": "http://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHqfeUkAA4a0Y.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
},
"source_status_id": 657745100739506176,
"source_status_id_str": "657745100739506176",
"source_user_id": 999716342,
"source_user_id_str": "999716342"
},
{
"id": 657745085275095040,
"id_str": "657745085275095040",
"indices": [
123,
140
],
"media_url": "http://pbs.twimg.com/media/CSDHq5CUwAAC-6a.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5CUwAAC-6a.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 453,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 800,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 768,
"h": 1024,
"resize": "fit"
}
},
"source_status_id": 657745100739506176,
"source_status_id_str": "657745100739506176",
"source_user_id": 999716342,
"source_user_id_str": "999716342"
},
{
"id": 657745085300277248,
"id_str": "657745085300277248",
"indices": [
123,
140
],
"media_url": "http://pbs.twimg.com/media/CSDHq5IVAAAn2YH.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5IVAAAn2YH.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 453,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 800,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 768,
"h": 1024,
"resize": "fit"
}
},
"source_status_id": 657745100739506176,
"source_status_id_str": "657745100739506176",
"source_user_id": 999716342,
"source_user_id_str": "999716342"
},
{
"id": 657745085275082752,
"id_str": "657745085275082752",
"indices": [
123,
140
],
"media_url": "http://pbs.twimg.com/media/CSDHq5CUkAAd0oL.jpg",
"media_url_https": "https://pbs.twimg.com/media/CSDHq5CUkAAd0oL.jpg",
"url": "https://t.co/95GaLC4XTo",
"display_url": "pic.twitter.com/95GaLC4XTo",
"expanded_url": "http://twitter.com/M23projects/status/657745100739506176/photo/1",
"type": "photo",
"sizes": {
"small": {
"w": 340,
"h": 255,
"resize": "fit"
},
"medium": {
"w": 600,
"h": 450,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 768,
"resize": "fit"
}
},
"source_status_id": 657745100739506176,
"source_status_id_str": "657745100739506176",
"source_user_id": 999716342,
"source_user_id_str": "999716342"
}
]
},
"favorited": false,
"retweeted": false,
"possibly_sensitive": false,
"filter_level": "low",
"lang": "en",
"timestamp_ms": "1445669074321"
}
**UPDATE: ** I guess I should stick to play-json, even more so for performance reasons - http://derekwyatt.org/2014/01/15/benchmarking-spray-json-argonaut-play-json/
You can depends on Play's JSON library by itself:
// build.sbt
libraryDependencies += "com.typesafe.play" % "play-json_2.11" % "X.X.X"
// Tweet.scala
import play.api.libs.json._
case class User(id: String, name: String, ...)
implicit val userFormat = Json.format[User]
case class Tweet(id: String, content: String, user: User)
implicit val tweetFormat = Json.format[Tweet]
This will use play-json's macros to auto-generate the formatters you need to parse JSON into instances of Tweet and User.
Regardless of library you choose you won't find an elegant solution for handling more than 22 fields since that's a limitation of the case class implementation (up until 2.11) rather than any specific design choice by a library.