Uncaught exception from servlet - JSON GAE deployment issue - json

I have created a script on browser that calls a servlet which is deployed on GAE. The servlet uses Datastore.
Everytime servlet is called I receive the following error
Uncaught exception from servlet java.lang.NoClassDefFoundError: org/json/JSONException
For development I use eclipse and Maven.
In pom.xml I have already included org.json 20090211 and javax.validation.
UPDATE
In order to better clarify my question I am posting code from servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = request.getReader();
String str;
while ((str = br.readLine()) != null)
{
sb.append(str);
}
String jsonResp = sb.toString();
JSONParser gparser = new JSONParser();
The problem appears on the last line, so I am posting code from JSONParser
public class JSONParser {
public ArrayList<String> ReturnGoogleJSON(String ResponseString) throws IOException {
ArrayList<String> Row = new ArrayList<String>();
try {
JSONObject rootObject = new JSONObject(ResponseString); // Parse the JSON to a JSONObject
JSONArray rows = rootObject.getJSONArray("items") ; // Get all JSONArray rows
for(int i=0; i < rows.length(); i++) { // Loop over each each row
JSONObject element = rows.getJSONObject(i); // Get the element object
Row.add(element.getString("tag"));
Row.add(element.getString("link"));
Row.add(element.getString("priority"));
}
} catch (JSONException e) {
e.printStackTrace();
}
return Row;
}
}
Could anyone help me with this kind of error?
Thank you in advance.

Check war/WEB-INF/lib directory of your project in eclipse before upload and make sure that json and other dependent files are present in this directory.
Edit:
You may want to check:
GAE - ClassNotFoundException after deployment to Appspot server
http://javanto.com/blog/2012/01/11/gae-eclipse-maven-2-0/

Related

Spring boot rest mvc json parser is not validating input json data which is illegal or has trailing data

In my rest client i am passing the below JSON request data:
{
"jobName":"test1",
"source":{ "name":"prod1","type":"teradata"},
"target":{ "name":"prod2","type":"teradata"},
"objects":{ "name":"table1"}<br/>
}
junkdata ; ##%$##%
So the extra "junkdata ; ##%$##%" not got validated by the rest client or by the spring jackson out-of-the box message converter.
I did debug the code, the spring HttpServletRequest body has the complete data including the junk data. As such its not failing, the spring is ignoring the junk data and converting the starting JSON data into Java object.
I did try by adding annotations like #JsonFormat for #RequestBody in rest controller calls (#RestController). But its not validating seems the Spring out-of-the box message converter jackson is not validating the incoming request JSON data properly.
Now this issue (failing on trailing tokens or data) is fixed in the spring jackson https://github.com/FasterXML/jackson-databind/issues/1583
using DeserializationFeature.FAIL_ON_TRAILING_TOKENS, Here is the code sample to fix the issue:
#Configuration
public class RestControllerConfiguration extends WebMvcConfigurationSupport
{
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
}
}
After working on different ways i got the solution using Google gson.jar, #Pete yes i have validate the JSON input which is invalid.
The google gson api is validating it properly, we need to use the custom message converter to validate it in the rest WebMvcConfigurationSupport class.
#Configuration
#ComponentScan(basePackages = { "com.teradata.datamovement.rest.controllers",
"com.teradata.rest.controller" })
public class RestControllerConfiguration extends WebMvcConfigurationSupport
{
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
log.debug("Adding custom message converter.");
converters.add(new AbstractHttpMessageConverter<Object>(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")){
#Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
try{
log.debug("Converting and validating the http request body data.");
String httpRequestBody = convertStreamToString(inputMessage.getBody());
log.debug("Http request body data:"+httpRequestBody);
return new Gson().fromJson(httpRequestBody, clazz);
}
catch(JsonSyntaxException e){
throw new HttpMessageNotReadableException("Invalid input JSON data: " + e.getMessage(), e);
}
}
private String convertStreamToString(InputStream is) throws IOException {
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
#Override
protected boolean supports(Class clazz) {
return true;
}
#Override
protected void writeInternal(Object t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(new Gson().toJson(t).getBytes());
}
});
}
}
But the weird thing i have noticed is that its working only if i make it as anonymous class or by adding the class with in the same file. If i create this custom message converter out side this RestControllerConfiguration.java file, then its not validating it.
Here is the example:
{
"jobName":"test1",
"source":{ "name":"prod1","type":"teradata"},
"target":{ "name":"prod2","type":"teradata"},
"objects":{ "name":"table1"}
}
junkdata ; ##%$##%
This will get validated, and will throw error like
{"message":"Invalid input JSON data: com.google.gson.stream.MalformedJsonException: Expected EOF at line 7 column 1; nested exception is com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected EOF at line 7 column 1"}

Java - Nested JSON objects

I am trying to create a simple JAVA remote for XBMC/KODI and I think im doing ok so far (still early days) but I have hit a snag when I reached a nested JSON object.
This is the original code I am converting to JAVA:
{"jsonrpc": "2.0", "method": "Player.PlayPause", "params": { "playerid": 0 }, "id": 1}
I have done this in JAVA so far:
public static void main(String[] args) throws UnknownHostException, IOException{
JSONObject json = new JSONObject();
json.put("jsonrpc", "2.0");
json.put("method", "Player.PlayPause");
//json.put("params", "playerid = 0"); THIS IS THE LINE I am having issues with
Socket s = new Socket("192.168.0.21", 8080);
try (OutputStreamWriter out = new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8)) {
out.write(json.toString());
}}
As you can see from the original JSON there is a nested {} within the {} so {{}} and I dont know how to handle this. Im using JSON-Simple in eclipse if this helps, thanks for any help!
EDIT:
So that was helpful thanks, but it doesnt actually work is there anything wrong with the syntax:
public static void main(String[] args) throws UnknownHostException, IOException{
JSONObject json = new JSONObject();
JSONObject params = new JSONObject();
json.put("jsonrpc", "2.0");
json.put("method", "Player.PlayPause");
params.put("playerid", 0);
json.put("params", params);
json.put("id", 1);
Socket s = new Socket("192.168.0.21", 8080);
try (OutputStreamWriter out = new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8)) {
out.write(json.toString());
}
}
Create another JSONObject for the params, set it up, and add it to the parent JSONObject with the key params.
//import java.util.ArrayList;
//import org.bson.Document;
Document root= new Document();
Document rootParams = new Document();
root.append("jsonrpc","2.0");
root.append("method","Player.PlayPause");
rootParams.append("playerid",0);
root.append("id",1);
if (!rootParams.isEmpty()){
root.append("params",rootParams);
}
System.out.println(root.toJson());

json =>json is not a know variable in the current context<

I am working on a project where I need to process JSON string and to test it I write the following code
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, ParseException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String res=null;
res= "{\"array\":[{\"title\":\"21 new minister join PM narendra modi's gov , shiv sena boycotts oath ceremony\",\"cat\":\"academic\"}]}";
out.print(res);
JSONObject json = new JSONObject(res);
out.print(json);
}catch(Exception e){
e.printStackTrace();
} finally {
out.close();
}
}
I already check the string res at http://pro.jsonlint.com/ and it approved this String.
I also debug the code and set the breakpoint at out.print(res) and it's working fine and then goes to out.close() without throwing any Exception. The debugger message is same as title "json =>json is not a know variable in the current context<"
if you want to pass your json data to the calling area as response then you need to change
out.print(json);
to
out.write(json.toString());
out.flush();

Camel route loop not working

I am trying to insert json data in mySQL database using camel and hibernate.
Everything is working.
for (Module module : modules) {
from("timer://foo?delay=10000")
.loop(7)//not working
.to(module.getUrl() + "/api/json")
.convertBodyTo(String.class)
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
int index = (Integer)exchange.getProperty("CamelLoopIndex"); // not working
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(exchange.getIn().getBody().toString());
String[] lijst = {"lastBuild", "lastCompletedBuild", "lastFailedBuild", "lastStableBuild", "lastSuccessfulBuild", "lastUnstableBuild", "lastUnsuccessfulBuild"};
JSONObject obj = new JSONObject();
JsonNode node = root.get(lijst[index]);
JsonNode build = node.get("number");
obj.put("description", lijst[index]);
obj.put("buildNumber", build);
exchange.getIn().setBody(obj.toString());
}
})
.unmarshal(moduleDetail)
.to("hibernate:be.kdg.teamf.model.ModuleDetail")
.end();
}
When I debug, my CamelLoopIndex remains 0 so it is not incremented every time it goes through the loop.
All help is welcome!
In your case the only first instruction is processed in scope of the loop: .to(module.getUrl() + "/api/json"). You can add more instructions into a loop using Spring DSL, but I don't know how to declare a loop scope using Java DSL explicitly. I hope experts will explain more about a loop scope in Java DSL.
As a workaround I suggest to move all iteration instructions to a separate direct: route.
I can't reproduce your problem. This works:
from("restlet:http://localhost:9010}/loop?restletMethod=get")
.loop(7)
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
int index = (int) exchange.getProperty("CamelLoopIndex");
exchange.getIn().setBody("index=" + index);
}
})
.convertBodyTo(String.class)
.end();
Output:
index=6

How do I send java string array to sencha touch list?

How do I send java string array to sencha touch list. I am using a servlet and gson and I get the error at the line JsonObject creation.
import com.google.gson.JsonObject;
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
String[] anArray;
anArray = new String[11]; //assign each element of array later
JsonObject myObj = new JsonObject();
PrintWriter out = response.getWriter();
for(int i = 0; i <11; i++){
myObj.addProperty(anArray[i], i);
}
out.println(myObj.toString());
out.close();
}
eg:-
The following link uses jdbc to serve it via a database.
http://www.mysamplecode.com/2012/05/sencha-touch-list-example.html
Similar to this but the data is to be taken from the array of strings.
Set your content type to application/json on line 4 -
response.setContentType("application/json");
and make sure you are sending properly formatted JSON from your servlet.