I am trying to get data from my SQL. The Data from my Servlet is put into an array list. After that I build a JSON object and pass it to my JSP file.
Now my browser is receiving the Objects really weird.
Also I can only call the first 3 of them. I tried to get all from the list with a for loop but that gave me an error. Any ideas what I am doing wrong?
Oh and I am also not allowed to use JQuery. :(
I receive my JSON like this:
{"id":"1GürtelA","kategorie":"2schuheS","oberkategorie":"3HoseB"}
But it should be:
{"id":"1", "kategorie":"Gürtel", "oberkategorie":"A"}
{"id":"2", "kategorie":"schuhe", "oberkategorie":"S"}
{"id":"3", "kategorie":"Hose", "oberkategorie":"B"}
Here is the Part of my Servlet:
List<KategorieBean> kategorien = displayKat();
HttpSession session = request.getSession();
session.setAttribute("kategorie", kategorien);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
String resultJson = Json.createObjectBuilder()
.add("id", (kategorien.get(0).toString()))
.add("kategorie", (kategorien.get(1).toString()))
.add("oberkategorie", (kategorien.get(2).toString()))
.build()
.toString();
PrintWriter writer = response.getWriter();
writer.print(resultJson);
writer.flush();
And here is toString I had to override.
#Override
public String toString() {
return id + kategorie + oberK ;
// This method is in my Bean
}
It seems you're using javax.json API, and your expected output is not valid JSON.
It should be an array:
[{"id":"1", "kategorie":"Gürtel", "oberkategorie":"A"},
{"id":"2", "kategorie":"schuhe", "oberkategorie":"S"},
{"id":"3", "kategorie":"Hose", "oberkategorie":"B"}]
To achieve this you need to fix your JSON building code (assuming that you have proper getters in the KategorieBean class):
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
for (KategorieBean category : kategorien) {
JsonObjectBuilder itemBuilder = Json.createObjectBuilder();
arrayBuilder.add(
itemBuilder
.add("id", category.getId())
.add("kategorie", category.getKategorie())
.add("oberkategorie", category.getOberK())
.build()
);
}
String resultJson = arrayBuilder.build().toString();
Also this code will return all items in the category list, not only the first three ones.
Related
I am currently using JsonObject and JsonParser of com.google.gson api (using gson-2.8.5 version) to parse and read the value form input JSON.
I have JSON filed like , smaple "resultCode":"SUCCESS", when I try to read the same value from json it gives the result as ""SUCCESS"" .
Every value I am reading, getting with double "" not sure why ? You can refer below screen of my debugging screen.
I am new to Json and parser, is that default behavior ?
I am expecting "SUCCESS", "S", "00000000" not like ""SUCCESS"" or ""S""
or ""00000000""
same I have highlighted in the below image .
Please share any idea how we can get apbsolute vlaue of string without """" double quote string it causing my string comparison fail.
String response_result = "{\"response\": {\"head\": {\"function\": \"acquiring.order.create\",\"version\": \"2.0\",\"clientId\": \"201810300000\",\"reqMsgId\": \"56805892035\",\"respTime\": \"2019-09-13T13:18:08+08:00\"},\"body\": {\"resultInfo\": {\"resultCode\": \"SUCCESS\",\"resultCodeId\": \"00000000\",\"resultStatus\": S,\"resultMsg\": \"SUCCESS\"},\"acquirementId\": \"2018080834569894848930\",\"merchantTransId\": \"5683668701112717398\",\"checkoutUrl\": \"http://localhost:8081/crm/operator/operator-search-init.action\"}},\"signature\":\"d+TUYLvt1a491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ==\"}";
HttpInvoker.Result result = i.new Result(200, response_result);
JsonObject jo = new JsonParser().parse(response_result).getAsJsonObject();
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").toString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCodeId").toString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultStatus").toString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("checkoutUrl").toString();
if ( RESULT_CODE_GCASH_SUCCESS.equals(resultCode)
&& RESULT_STATUS_SUCCESS.equals(resultStatus)
&& StringUtils.isNotEmpty(checkoutUrl)) {
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
This is my input JSON
{
"response":{
"head":{
"function":"acquiring.order.create",
"version":"2.0",
"clientId":"201810300000",
"reqMsgId":"56805892035",
"respTime":"2019-09-13T13:18:08+08:00"
},
"body":{
"resultInfo":{
"resultCode":"SUCCESS",
"resultCodeId":"00000000",
"resultStatus":"S",
"resultMsg":"SUCCESS"
},
"acquirementId":"2018080834569894848930",
"merchantTransId":"5683668701112717398",
"checkoutUrl":"http://localhost:8081/crm/operator/operator-search-init.action"
}
},
"signature":"d+TUYLvtI38YL2hresd98Ixu1BXccvvh1IQMiHuMXUEeW/N5exUsW491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ=="
}
JsonParser parses your json into JsonElement structure. The behaviour that you see is a normal since you are using toString method of JsonElement. To achieve your goal just use JsonElement::getAsString method :
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").getAsString();
which gives SUCCESS instead of "SUCCESS"
Note that JsonElement is an abstract class and classes, that extend this class, will override those helper getAs... methods. In your case JsonPrimitive::getAsString will be invoked.
Also you could create a POJO class for your json and use Gson::fromJson to parse json into object of your POJO class.
With the input from #Michalk:
I understand that easy way to read JSON data is using Gson::fromJson and creating POJO class for out json.
I have generated POJO Classes supplying my sample input JSON using this link
and Now I have POJO Classes called : CreateOrderJSONResponse
Gson::fromJson
Sample :
Gson gson = new Gson();
CreateOrderJSONResponse responseJson = gson.fromJson(inputJSON, CreateOrderJSONResponse.class);
Accessubg data :
String resultCodeText = responseJson.getResponse().getBody().getResultInfo().getResultCode();
String resultCodeId = responseJson.getResponse().getBody().getResultInfo().getResultCodeId();
String resultStatus = responseJson.getResponse().getBody().getResultInfo().getResultStatus();
String checkoutUrl = responseJson.getResponse().getBody().getCheckoutUrl();
Above Gson::fromJson example works smooth and it looks neat compare to direct accessing the filed with below sample code :
JsonObject jo = parser.parse(inputJSON).getAsJsonObject();
String resultCodeText = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCode").getAsString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCodeId").getAsString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultStatus").getAsString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().getAsJsonPrimitive("checkoutUrl").getAsString();
Note :
I have found this link of JSON or JAVA, SCALA, POJO generator tools as GitHub access you can access here
My servlet recieves/loads multiple parameters from/for an article (price, id, count, name).
While they are saved in the session for other purposes I want to display them in a Shopping cart.
So my idea was to get all values into a json like this
{"id":1, "prductName":"article1"}
but my json always ends up empty.
I had two approaches:
String prname = request.getParameter("name");
String anz = String.valueOf(session.getAttribute("Anzahl"));
String prid = request.getParameter("id");
String price = request.getParameter("price");
These are my parameters:
First try:
class ToJson{
String prname1 = String.valueOf(session.getAttribute("prname"));
String anz1 = String.valueOf(session.getAttribute("Anzahl"));
String prid1 = String.valueOf(session.getAttribute("id"));
String price1 = String.valueOf(session.getAttribute("price"));
}
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn1 = jsonb.toJson(obj);
Ends up with: {}
Second try:
ArrayList<String> ar = new ArrayList<String>();
ar.add(prname);
ar.add(price);
ar.add(prid);
ar.add(anz);
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn = jsonb.toJson(ar);
Ends up with: ["P1neu","25","1","145"]
It isn't in a format I wanted and I also don't know how to access the seperate values here, I tried jsn[1] but it didnt work.
Could you help me, please?
To your first question, why JSON object is printing empty:
You are missing getters & setters in the ToJSON class for JSON Builder/Parser to access the properties/fields, and that's why its printing as empty object.
To your second question, how do I access JSON properties:
JSON representation is a natively a string representation, and you can't read part of string as jsn[1].
For reading JSON object properties, you convert it into POJO using available any of preferred open source parser libraries like Jacksons, Gson etc. And then access POJO properties using standard java getter/setters.
I realize my questions have been asked a lot but I have spent a considerable amount of time scouring both SO and google trying to get a better understanding of this concept with no success. I've seen many different implementations, which is what leads me to get some advice about my specific situation.
MY OBJECTIVE
I need to perform a post request to a php file and the goal is to ultimately populate fields in a list activity with some of the json data.
HTTP POST RESPONSE
Here is the format of the response data I'm getting back from the server, which appears to be a JSON object of arrays(?).
{"expense":[{"cat_id_PK":237,"cat_name":"Name1","cat_amount":"100.00","is_recurring":0},
{"cat_id_PK":238,"cat_name":"Name2","cat_amount":"200.00","is_recurring":0},
{"cat_id_PK":239,"cat_name":"Name3","cat_amount":"300.00","is_recurring":0},
{"cat_id_PK":240,"cat_name":"Name4","cat_amount":"400.00","is_recurring":0}],
"expense_rec": [{"cat_id_PK":207,"cat_name":"Name5","cat_amount":"500.00","is_recurring":1}]}
FIRST QUESTION
The code below is what I'm using to read the response. Is this how I should be handling that? It seems weird to get a json encoded response and then change it to a string, only to try and access elements of a json object again. Am I on the wrong track here?
//This code is in the doInBackground method of my "sendPostRequest" async task.
HttpResponse httpResponse = httpClient.execute(httpPost);
InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String bufferedStrChunk = null;
while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
stringBuilder.append(bufferedStrChunk);
}
//Returns string to onPostExecute()
return stringBuilder.toString();
SECOND QUESTION
I have another file called "PostResponse.java" that holds the following code I modeled after a tutorial online. I'm unsure of how to interact with this class from the onPostExecute method. How can I access say, the first item in the first object (something like in PHP where you could do: expense[0]['cat_name']). I've tried to do this various ways with no success. Here is the PostResponse.java class:
public class PostResponse {
public Integer cat_id_PK;
public String cat_name;
public BigDecimal cat_amount;
public Integer is_recurring;
public int getID() {
return this.cat_id_PK;
}
public void setID(int cat_id_PK){
this.cat_id_PK = cat_id_PK;
}
public String getName() {
return this.cat_name;
}
public void setName(String cat_name) {
this.cat_name = cat_name;
}
public BigDecimal getAmount() {
return this.cat_amount;
}
public void setAmount(BigDecimal cat_amount) {
this.cat_amount = cat_amount;
}
public int getRecurring() {
return this.is_recurring;
}
public void setRecurring(int is_recurring) {
this.is_recurring = is_recurring;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("*** Categories ***");
sb.append("cat_id_PK="+getID()+"\n");
sb.append("cat_name="+getName()+"\n");
sb.append("cat_amount="+getAmount()+"\n");
sb.append("is_recurring="+getRecurring()+"\n");
return sb.toString();
}
}
and here is the content of my onPostExecute method:
protected void onPostExecute(String result) {
super.onPostExecute(result);
Gson gson = new Gson();
PostResponse response = gson.fromJson(result, PostResponse.class);
System.out.println(result);
}
Like I said originally, my ultimate goal is to populate these items to a list activity, but at this point I'd settle for just knowing how to get at specific elements. However, if anyone would like to include how to populate a list activity in their response, it would save me a lot more headaches, as nothing with java is coming easy for me!
FIRST QUESTION
The code below is what I'm using to read the response. Is this how I should be handling that? It seems weird to get a json encoded response and then change it to a string, only to try and access elements of a json object again. Am I on the wrong track here?
It's one way of handling the http response. A "json encoded response" is little more than a text-based response, so converting it into a string on the receiving end would make sense. That is, the json you receive isn't an 'object' as far as Java is concerned: it's just textual representation of an object (or a bunch of objects in your case), received as a stream of bytes.
That being said, you can potentially shorten your code by skipping the string(builder) part. Gson provides an alternative constructor that takes a Reader instance, for which you can suppy the BufferedReader in your code snippet.
As a side note: the conversion of textual json into Java objects is a potentially 'heavy' operation. As such, you'd best avoid doing it on the main/ui thread, so just move it into the doInBackground() method of your AsyncTask (and change types appropriately).
SECOND QUESTION
I have another file called "PostResponse.java" that holds the following code I modeled after a tutorial online. I'm unsure of how to interact with this class from the onPostExecute method. How can I access say, the first item in the first object (something like in PHP where you could do: expense[0]['cat_name']). I've tried to do this various ways with no success.
You're close, but if you look more closely to the json sample, you'll see that your PostResponse class is not a good match for it:
{
"expense": [
{
"cat_id_PK": 237,
"cat_name": "Name1",
"cat_amount": "100.00",
"is_recurring": 0
},
{
"cat_id_PK": 238,
"cat_name": "Name2",
"cat_amount": "200.00",
"is_recurring": 0
},
{
"cat_id_PK": 239,
"cat_name": "Name3",
"cat_amount": "300.00",
"is_recurring": 0
},
{
"cat_id_PK": 240,
"cat_name": "Name4",
"cat_amount": "400.00",
"is_recurring": 0
}
],
"expense_rec": [
{
"cat_id_PK": 207,
"cat_name": "Name5",
"cat_amount": "500.00",
"is_recurring": 1
}
]
}
Consider the more hierarchical formatting above. On the first level there are two (json) objects: expense and expense_rec (both contain 0...* elements, as the square brackets indicate). That means that whatever class you're going to be trying to map the json onto, should define these fields too. If you now look at your PostResponse class, it should become obvious that in its current form it in fact models one of the child objects of the aforementioned fields.
Basically, the classes to map the json onto, should look somewhat like this:
PostResponse:
public class PostResponse {
public ExpenseItem[] expense;
public ExpenseItem[] expense_rec;
// List<ExpenseItem> is also supported
// getters & setters
}
ExpenseItem:
public class ExpenseItem {
public Integer cat_id_PK;
public String cat_name;
public BigDecimal cat_amount;
public Integer is_recurring;
// getters & setters
}
With the model classes defined, try to let Gson work its magic again. If all goes well, you should be able to access the data in a way similar to what you're used to in PHP:
// map json to POJOs
PostResponse response = new Gson().fromJson(bufferedReader, PostResponse.class);
// retrieve the cat_name for the first item (assuming there is one)
String catName = response.getExpense()[0].getName();
... or any of the other fields through the getters defined in ExpenseItem.
Once you have this part working, it's going to be fairly straightforward to supply the array or list of expenses to an adapter (have a look at ArrayAdapter in the Android framenwork) and bind that adapter to a ListView.
The answer is yes, you will get the response in InputStream
For your second question check this out - jsonschema2pojo this can be helpful while creating models for your JSON data.
Then to use GSON
Gson gson = new Gson();
YourObj yourObj = (YourObj) gson.fromJson(result, YourObj.class);
The answer is yes.Response is received as InputSteam
protected void onPostExecute(String result)
{
super.onPostExecute(result);
Gson gson = new Gson();
PostResponse response = gson.fromJson(result, PostResponse.class);
System.out.println(result);
}
This code section mostly means that after an AsyncTask that get web Response and get the String format json response,this onPostExecute will be called with that Stringfied json.
Gson gson = new Gson();
Gson is a library supported by Google for android to deserialization into your class OBject.
gson.fromJson(result, PostResponse.class);
This method is the real process of deserialization. result is Stringfied json and the second is the Target class you want to deserialize into.
This will return a PostResponse Object and you can use it now.
For the json data (
{"expense":[{"cat_id_PK":237,"cat_name":"Name1","cat_amount":"100.00","is_recurring":0},
{"cat_id_PK":238,"cat_name":"Name2","cat_amount":"200.00","is_recurring":0},
{"cat_id_PK":239,"cat_name":"Name3","cat_amount":"300.00","is_recurring":0},
{"cat_id_PK":240,"cat_name":"Name4","cat_amount":"400.00","is_recurring":0}],
"expense_rec": [{"cat_id_PK":207,"cat_name":"Name5","cat_amount":"500.00","is_recurring":1}]}),
it contains two different arrays here, one is "expense" and another is "expense_rec". So if you want to populate these items to a list activity, you can try the follow methods.
protected void onPostExecute(String result) {
super.onPostExecute(result);
JSONObject jsonObject = new JSONObject(builder.toString());
Log.i(TAG, "jsonObject is : " + jsonObject.toString());
//this is the first array data
JSONArray jsonArray = jsonObject.getJSONArray("expense");
Log.i(TAG, "Array length is: " + jsonArray.length());
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsoObj = jsonArray.getJSONObject(i);
String name = jsoObj.getString("cat_name");
Log.i(TAG, "file name is: " + name);
}
//this is the second array data
jsonArray = jsonObject.getJSONArray("expense_rec");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsoObj = jsonArray.getJSONObject(i);
String name = jsoObj.getString("cat_name");
Log.i(TAG, "file name is: " + name);
}
}
I have JSON as a string and a JSONPath as a string. I'd like to query the JSON with the JSON path, getting the resulting JSON as a string.
I gather that Jayway's json-path is the standard. The online API, however, doesn't have have much relation to the actual library you get from Maven. GrepCode's version roughly matches up though.
It seems like I ought to be able to do:
String originalJson; //these are initialized to actual data
String jsonPath;
String queriedJson = JsonPath.<String>read(originalJson, jsonPath);
The problem is that read returns whatever it feels most appropriate based on what the JSONPath actually finds (e.g. a List<Object>, String, double, etc.), thus my code throws an exception for certain queries. It seems pretty reasonable to assume that there'd be some way to query JSON and get JSON back; any suggestions?
Java JsonPath API found at jayway JsonPath might have changed a little since all the above answers/comments. Documentation too. Just follow the above link and read that README.md, it contains some very clear usage documentation IMO.
Basically, as of current latest version 2.2.0 of the library, there are a few different ways of achieving what's been requested here, such as:
Pattern:
--------
String json = "{...your JSON here...}";
String jsonPathExpression = "$...your jsonPath expression here...";
J requestedClass = JsonPath.parse(json).read(jsonPathExpression, YouRequestedClass.class);
Example:
--------
// For better readability: {"store": { "books": [ {"author": "Stephen King", "title": "IT"}, {"author": "Agatha Christie", "title": "The ABC Murders"} ] } }
String json = "{\"store\": { \"books\": [ {\"author\": \"Stephen King\", \"title\": \"IT\"}, {\"author\": \"Agatha Christie\", \"title\": \"The ABC Murders\"} ] } }";
String jsonPathExpression = "$.store.books[?(#.title=='IT')]";
JsonNode jsonNode = JsonPath.parse(json).read(jsonPathExpression, JsonNode.class);
And for reference, calling 'JsonPath.parse(..)' will return an object of class 'JsonContent' implementing some interfaces such as 'ReadContext', which contains several different 'read(..)' operations, such as the one demonstrated above:
/**
* Reads the given path from this context
*
* #param path path to apply
* #param type expected return type (will try to map)
* #param <T>
* #return result
*/
<T> T read(JsonPath path, Class<T> type);
Hope this help anyone.
There definitely exists a way to query Json and get Json back using JsonPath.
See example below:
String jsonString = "{\"delivery_codes\": [{\"postal_code\": {\"district\": \"Ghaziabad\", \"pin\": 201001, \"pre_paid\": \"Y\", \"cash\": \"Y\", \"pickup\": \"Y\", \"repl\": \"N\", \"cod\": \"Y\", \"is_oda\": \"N\", \"sort_code\": \"GB\", \"state_code\": \"UP\"}}]}";
String jsonExp = "$.delivery_codes";
JsonNode pincodes = JsonPath.read(jsonExp, jsonString, JsonNode.class);
System.out.println("pincodesJson : "+pincodes);
The output of the above will be inner Json.
[{"postal_code":{"district":"Ghaziabad","pin":201001,"pre_paid":"Y","cash":"Y","pickup":"Y","repl":"N","cod":"Y","is_oda":"N","sort_code":"GB","state_code":"UP"}}]
Now each individual name/value pairs can be parsed by iterating the List (JsonNode) we got above.
for(int i = 0; i< pincodes.size();i++){
JsonNode node = pincodes.get(i);
String pin = JsonPath.read("$.postal_code.pin", node, String.class);
String district = JsonPath.read("$.postal_code.district", node, String.class);
System.out.println("pin :: " + pin + " district :: " + district );
}
The output will be:
pin :: 201001 district :: Ghaziabad
Depending upon the Json you are trying to parse, you can decide whether to fetch a List or just a single String/Long value.
Hope it helps in solving your problem.
For those of you wondering why some of these years-old answers aren't working, you can learn a lot from the test cases.
As of September 2018, here's how you can get Jackson JsonNode results:
Configuration jacksonConfig = Configuration.builder()
.mappingProvider( new JacksonMappingProvider() )
.jsonProvider( new JacksonJsonProvider() )
.build();
JsonNode node = JsonPath.using( jacksonConfig ).parse(jsonString);
//If you have a json object already no need to initiate the jsonObject
JSONObject jsonObject = new JSONObject();
String jsonString = jsonObject.toString();
String path = "$.rootObject.childObject"
//Only returning the child object
JSONObject j = JsonPath.read(jsonString, path);
//Returning the array of string type from the child object. E.g
//{"root": "child":[x, y, z]}
List<String> values = sonPath.read(jsonString, path);
Check out the jpath API. It's xpath equivalent for JSON Data. You can read data by providing the jpath which will traverse the JSON data and return the requested value.
This Java class is the implementation as well as it has example codes on how to call the APIs.
https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java
Readme -
https://github.com/satyapaul/jpath/blob/master/README.md
I have this method :
#GET
#Path("/myservice")
#Produces(MediaType.APPLICATION_JSON)
public Response mysercice() {
boolean userExists = false;
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoStore(true);
JSONObject jsonObject = new JSONObject();
jsonObject.put("userExists", userExists);
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
}
When accessing to the URL of the method in the browser, I get { }, it means that the object is empty.
So, I tried to use :
return Response.ok(jsonObject.toString(), MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
So, I get in the browser {"userExists" : false}
But I didn't understand why when returning simply the JSONObject, we get in the browser an empty object.
Most JAX-RS implementations come with a provider for mapping response entities to JSON. So when you write:
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).build();
You are basically requesting that the JAX-RS provider marshall the JSONObject into JSON for you. The only problem being that JSONObject isn't really meant to be serialized this way. Instead its meant to be used to build a JSON representation incrementally, then convert that representation into a JSON string value. You have two options:
Create a POJO containing all the fields you want to send back to the client. Return this POJO in your method and it will be automatically converted to JSON (`return Response.ok(myPojo, MediaType.APPLICATION_JSON).build()
Return the JSON data directly as a String (which you already did in your example that works).