Reputation: 127
I wrote a java application (commandline app) initially and now I am trying to convert it to a web application using jersey and jetty embeded. Now as the output of a service rest class I need to output a List<List<Map<String,String>>>
in json format. Is there a way to accomplish this? I am new to the world of servlets and stuff.. i tried like this :
@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public List>> test( ) throws FileNotFoundException, IOException, GateException, URISyntaxException {
System.out.println("Starting the App");
System.out.println("Locations added successfully");
DataFile file = new CSVDataFile();
CommandsExecutor.outputsList.add(0, file.performReadOperation(inputFilePath));
System.out.println("Begining execution");
List<List<Map<String, String>>> finalOutput = CommandsExecutor.executeSequentialCommands(file);
/* for (List<Map<String, String>> tmpList : finalOutput) {
for (int i = 0; i < tmpList.size(); i++) {
Map<String, String> insideMap = tmpList.get(i);
// for (Map.Entry<String, String> entry : insideMap.entrySet())
// {
// System.out.println(entry.getKey() + "/" + entry.getValue());
// }
JSONObject obj = new JSONObject(insideMap);
System.out.println(obj);
}
System.out.println("\n");
} */
return finalOutput;
}
Now I get an error like this : Could not send response error 500: javax.servlet.ServletException: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List>>.
What could be the work around ? Thanks in advance!!
Upvotes: 2
Views: 4052
Reputation: 2366
Your result JSON could be something like:
{
"result":
[
[
{
"key1":"value1",
"key2":"value2",
...
},
{
"key3":"value3",
"key4":"value4"
...
},
...
],
...
]
}
In your commented code, you actually already created the inner JSONObject
for the maps, you just need to append them to a JSONArray
, and then put these JSONArray
s into another JSONArray
, then put this final JSONArray
in a result JSONObject
and return it.
JSONObject result = new JSONObject();
JSONArray array1 = new JSONArray();
for (List<Map<String, String>> tmpList : finalOutput) {
JSONArray array2 = new JSONArray();
for (int i = 0; i < tmpList.size(); i++) {
Map<String, String> insideMap = tmpList.get(i);
JSONObject obj = new JSONObject(insideMap);
array2.add(obj);
}
array1.add(array2);
}
result.append("result", array1);
return result.toString();
Upvotes: 1
Reputation: 890
The root cause of the problem is missing jars. Jersey makes use of Jackson, so you're going to need to download the Jackson jars.
Here's a list of all the Jackson jars I needed for a sample app I put together:
In my example I created the following class:
package foo;
import java.util.*;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class ListWrapper
{
private List<List<Map<String,String>>> list;
public List<List<Map<String,String>>> getList()
{
return list;
}
public void setList(List<List<Map<String,String>>> list)
{
this.list = list;
}
}
And this servlet class:
package foo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/foo")
public class Foo {
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public ListWrapper getList()
{
ListWrapper lw = new ListWrapper();
HashMap<String,String> map = new HashMap<String,String>();
map.put("foo", "bar");
map.put("hello", "world");
ArrayList<Map<String,String>> innerList = new ArrayList<Map<String,String>>();
innerList.add(map);
ArrayList<List<Map<String,String>>> outerList = new ArrayList<List<Map<String,String>>>();
outerList.add(innerList);
lw.setList(outerList);
return lw;
}
}
The following XML was added to the web.xml config in my app:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>foo,com.fasterxml.jackson.jaxrs.json</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Requesting the servlet in a browser returned the following JSON:
{
"list": [
[
{
"foo": "bar",
"hello": "world"
}
]
]
}
Once you get over the struggle of identifying all of the dependencies of Jersey and Jackson, they're really quite powerful libraries.
Upvotes: 2