JSONArray is not consuming full response from HTTPServletResponse - json

I'm filtering a response from a Filter in my Spring Boot application.
My requirement is to get the response Body. I'm using below method. But when i was debugging the complete response(JSONArray) as an array is missing. the response looks like at the end "crea..." and last part is missing with "]".
I'm using ContentCachingResponseWrap to cache the response.
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
request = (HttpServletRequest) servletRequest;
response = (HttpServletResponse) servletResponse;
ContentCachingResponseWrapper multiReadResponse =new ContentCachingResponseWrapper(response);
chain.doFilter(request, multiReadResponse);
InputStream responseInputStream = multiReadResponse.getContentInputStream();
JSONArray jsonArray = new JSONArray(new JSONTokener(inputStream));
multiReadResponse.copyBodyToResponse();
}
How I am missing the full response.

IDE shows '...' after a certain number of length. you need to increase it if you want to see the full length. This question was answered here. Viewing complete strings while debugging in Eclipse

Related

how to redirect to a new page from servlet

I am sending data to the servlet from login.html using JQuery in json format to the servlet and after matching the record i want to open a new page home.html and i also want to send the data to home.html:
DTORegisteration dto=new DTORegisteration();
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter pw = res.getWriter();
String id = req.getParameter("id");
String password = req.getParameter("password");
System.out.println("id "+id);
System.out.println("password "+password);
dto.setId(id);
dto.setPassword(password);
String str=new ServiceRegisteration().getDetails(dto);
JSONObject json=new JSONObject();
if(str.equals("success")) {
try { json.put("welcome", "welcome"); json.put("name",
DAORegisteration.name);
}catch(JSONException e) { e.printStackTrace(); }
pw.print(json);
}
}
The sendRedirect() method of HttpServletResponse interface can be used to redirect response to another resource, that may be servlet, jsp or html file.
if(check your param values here) { // if its as expected
res.sendRedirect("home.html");
}
Actually
we cannot send a post request using sendRedirect() method because as per standards redirect should use get.
You can use RequestDispatcher Class to forward() requests with parameters,
e.g.-
req.setAttribute("Greetings", "Greeting of day");
RequestDispatcher dispatcher = servletContext().getRequestDispatcher("url");
dispatcher.forward(req, res);

How to make JSON PUT request through Codename one API

I'm not able top figure out JSON put request from codename one api. I didnt find any example to make this request.
Questions:
1. I'm not sure whether I have to send the content length parameter. If yes, how can I send that?
2. I have to send the request body with just "true" nothing else. There is no key and value to use req.addArgument() method.
3. Do I have to use buildRequestBody() method to override the request. Can you provide an example?
4. How to verify the result after receiving the response.
Any help can be appreciated.
Thanks.
Please find the code below.
req.setUrl(identityUrl );
req.setPost(false);
req.setHttpMethod("PUT");
req.setContentType("application/json");
req.addRequestHeader("authorization", token);
req.addArgument("Content-Length", "4");
req.setReadResponseForErrors(true);
InfiniteProgress ip = new InfiniteProgress();
Dialog d = ip.showInifiniteBlocking();
NetworkManager.getInstance().addToQueueAndWait(req);
d.dispose();
JSONParser parser = new JSONParser();
Map map2 = null;
try {
map2 = parser.parseJSON(new InputStreamReader(new ByteArrayInputStream(req.getResponseData()), "UTF-8"));
} catch (IOException ex) {
ex.printStackTrace();
}
If you want the content to be embedded wholly you need to override the buildRequestBody method. Notice that post needs to be true for the body to be called.
I don't think you need content-length:
req = new ConnectionRequest(identityUrl) {
protected void buildRequestBody(OutputStream os) throws IOException {
os.write(json.getBytes("UTF-8"));
}
protected void readResponse(InputStream input) throws IOException {
map2 = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
}
protected void postResponse() {
// response completed, this is called on the EDT do the application logic here...
}
};
req.setPost(true);
req.setHttpMethod("PUT");
req.setContentType("application/json");
req.addRequestHeader("authorization", token);
req.setReadResponseForErrors(true);
InfiniteProgress ip = new InfiniteProgress();
Dialog d = ip.showInifiniteBlocking();
req.setDisposeOnCompletion(d);
NetworkManager.getInstance().addToQueue(req);
Notice that I no longer need to close streams or handle IOException as the connection request does everything for me. Also notice the read/build methods are called on the network threads and not on the EDT so you need to do the rest of the flow in the postResponse.

Spring Boot replace ServletException response in Filter

I have a Spring Boot Filter that I'm using to authenticate using Jwt. If successful, everything works great and I send out a Json response of my design. However, if the Authorization header is missing or incorrect, I throw a ServletException with a custom message. This results in an ugly Json that looks like this:
{
"timestamp":1453192910756,
"status":500,
"error":"Internal Server Error",
"exception":"javax.servlet.ServletException",
"message":"Invalid Authorization header.",
"path":"/api/test"
}
I wish to customize this Json so it takes the standard form I'm using for all my other responses.
My Filter code is here:
public class JwtFilter extends GenericFilterBean {
#Override
public void doFilter(final ServletRequest req,
final ServletResponse res,
final FilterChain chain) throws IOException, ServletException {
System.out.println("JwtFilter");
final HttpServletRequest request = (HttpServletRequest) req;
final String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
throw new ServletException("Missing Authorization header.");
}
if (!authHeader.startsWith("Bearer ")) {
throw new ServletException("Invalid Authorization header.");
}
final String token = authHeader.substring(7);
try {
final Claims claims = Jwts.parser().setSigningKey("secretkey")
.parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
}
catch (final SignatureException e) {
throw new ServletException("Invalid token.");
}
chain.doFilter(req, res);
}
}
I tried using a wrapper to wrap the response but that didn't work. Another SO post said the response was not changeable but that wouldn't even make sense.
I think the correct way would be to edit the ServletResponse res but I couldn't get it to work.
Thanks!
EDIT: Kind of hacky but it works. If there's a better way, please answer:
public class JwtFilter extends GenericFilterBean {
#Override
public void doFilter(final ServletRequest req,
final ServletResponse res,
final FilterChain chain) throws IOException, ServletException {
System.out.println("JwtFilter");
final HttpServletRequest request = (HttpServletRequest) req;
final String authHeader = request.getHeader("Authorization");
if (authHeader == null) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Missing Authorization header."));
return;
}
if (!authHeader.startsWith("Bearer ")) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Invalid Authorization header."));
return;
}
final String token = authHeader.substring(7);
try {
final Claims claims = Jwts.parser().setSigningKey("secretkey")
.parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
}
catch (Exception f) {
res.setContentType("application/json;charset=UTF-8");
res.getWriter().write(ExceptionCreator.createJson("Invalid token."));
return;
}
chain.doFilter(req, res);
}
}
In general, wrapping the response and then modifying the response output stream after the call to doFilter is the correct approach, e.g.
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrapper);
CharArrayWriter caw = new CharArrayWriter();
caw.write("your json");
response.setContentLength(caw.toString().getBytes().length);
out.write(caw.toString());
out.close();
Taken from Oracle JavaEE 5 Tutorial
Nevertheless, your usecase seems more appropriate for being dealt with in a RestController handler method, possibly in conjunction with an #ExceptionHandler(ServletException.class) annotated method. This would be a more generic approach that allows you to harness the power of Spring's content negotiation to deal with the JSON serialization.

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();

Tomcat servlet acting strange with json object

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
Gson gson = new Gson();
LocationTypes locTypes = new LocationTypes();
String json = gson.toJson(locTypes);
out.print(json);
out.flush();
}
If i take the above code, and System.out.println(json), it looks like this :
{"locationTypes":["Hospital","Church","Restaurant","Bar","Other"]}
What i get in the browser, when pointing to the url for the servlet, i get this:
{"calls":{"threadLocalHashCode":-2084311414},"typeTokenCache":{"com.google.gson.InstanceCreator\u003c?\u003e":{},"int":{},"java.lang.String":{},"java.lang.String[]":{},"java.util.Map\u003ccom.google.gson.reflect.TypeToken\u003c?\u003e, com.google.gson.TypeAdapter\u003c?\u003e\u003e":{},"java.util.List\u003ccom.google.gson.TypeAdapterFactory\u003e":{},"java.lang.ThreadLocal\u003cjava.util.Map\u003ccom.google.gson.reflect.TypeToken\u003c?\u003e, com.google.gson.Gson$FutureTypeAdapter\u003c?\u003e\u003e\u003e":{},"com.google.gson.TypeAdapterFactory":{},"com.google.gson.JsonDeserializationContext":{},"com.google.gson.reflect.TypeToken\u003c?\u003e":{},"java.util.Map\u003cjava.lang.reflect.Type, com.google.gson.InstanceCreator\u003c?\u003e\u003e":{},"com.google.gson.Gson":{},"boolean":{},"java.lang.reflect.Type":{},"data.LocationTypes":{},"java.lang.Class\u003c? super ?\u003e":{},"java.lang.Integer":{},"com.google.gson.internal.ConstructorConstructor":{},"com.google.gson.TypeAdapter\u003c?\u003e":{},"com.google.gson.JsonSerializationContext":{}},"factories":[null,null,{"version":-1.0,"modifiers":136,"serializeInnerClasses":true,"requireExpose":false,"serializationStrategies":[],"deserializationStrategies":[]},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,{"constructorConstructor":{"instanceCreators":{}}},{"constructorConstructor":{"instanceCreators":{}},"complexMapKeySerialization":false},{"constructorConstructor":{"instanceCreators":{}},"fieldNamingPolicy":"IDENTITY","excluder":{"version":-1.0,"modifiers":136,"serializeInnerClasses":true,"requireExpose":false,"serializationStrategies":[],"deserializationStrategies":[]}}],"constructorConstructor":{"instanceCreators":{}},"serializeNulls":false,"htmlSafe":true,"generateNonExecutableJson":false,"prettyPrinting":false}
Update
I have reproduced your error.
Unfortunately, you are passing the gson object to be converted to JSON.
Your problem is the result of a typo/mistake.
I ran the following code:
public static void main (String args[])
{
Gson gson = new Gson();
String json = gson.toJson(gson);
System.out.println(json);
}
And received the following:
{"calls":{"threadLocalHashCode":1253254570},"typeTokenCache":{"com.google.gson.Gson":{},"com.google.gson.reflect.TypeToken\u003c?\u003e":{},"com.google.gson.internal.ConstructorConstructor":{},"com.google.gson.InstanceCreator\u003c?\u003e":{},"java.lang.reflect.Type":{},"boolean":{},"int":{},"com.google.gson.JsonDeserializationContext":{},"com.google.gson.JsonSerializationContext":{},"java.lang.ThreadLocal\u003cjava.util.Map\u003ccom.google.gson.reflect.TypeToken\u003c?\u003e, com.google.gson.Gson$FutureTypeAdapter\u003c?\u003e\u003e\u003e":{},"java.util.List\u003ccom.google.gson.TypeAdapterFactory\u003e":{},"java.util.Map\u003cjava.lang.reflect.Type, com.google.gson.InstanceCreator\u003c?\u003e\u003e":{},"com.google.gson.TypeAdapter\u003c?\u003e":{},"java.lang.Integer":{},"com.google.gson.TypeAdapterFactory":{},"java.lang.Class\u003c? super ?\u003e":{},"java.util.Map\u003ccom.google.gson.reflect.TypeToken\u003c?\u003e, com.google.gson.TypeAdapter\u003c?\u003e\u003e":{}},"factories":[null,null,{"version":-1.0,"modifiers":136,"serializeInnerClasses":true,"requireExpose":false,"serializationStrategies":[],"deserializationStrategies":[]},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,{"constructorConstructor":{"instanceCreators":{}}},{"constructorConstructor":{"instanceCreators":{}},"complexMapKeySerialization":false},{"constructorConstructor":{"instanceCreators":{}},"fieldNamingPolicy":"IDENTITY","excluder":{"version":-1.0,"modifiers":136,"serializeInnerClasses":true,"requireExpose":false,"serializationStrategies":[],"deserializationStrategies":[]}}],"constructorConstructor":{"instanceCreators":{}},"serializeNulls":false,"htmlSafe":true,"generateNonExecutableJson":false,"prettyPrinting":false}
Kudos to Pragmateek for also checking the GSON SVN repo.
Original Answer
It's really quite impossible that System.out.println(json); would give you a different result than
out.print(json);
out.flush();
json is a String and dispays the same in any stream.
Have you checked that you don't have a typo somewhere?
I would suggest you copy and paste the code exactly as is within your project.
In the browser, you are getting a JSON version of an object that has serialized all the object's values/fields to JSON.
Many of the keys within your generated JSON are actual fields of the object your trying to serialize to JSON as Pragmateek has said.
It could almost be suspected that your are passing your GSON object to be converted to JSON....
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
Gson gson = new Gson();
LocationTypes locTypes = new LocationTypes();
String json = gson.toJson(locTypes);
response.setContentType("application/json");
out.print(json);
out.flush();
}
try setting content-type as above
Is this the original code?
Are you sure there isn't a typo like:
out.print(gson);
Because the strange JSON really looks like a serialized GSON library object...