2
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.json.JSONObject;

  // Extend HttpServlet class
  public class Test extends HttpServlet {
  JSONObject json = new JSONObject();

  public void init() throws ServletException
  {
     json.put("city", "Mumbai");
     json.put("country", "India");
  }

  public void doGet(HttpServletRequest request,
                HttpServletResponse response)
       throws ServletException, IOException
  {
       response.setContentType("application/json");
       String output = json.toString();
  }

  public void destroy()
  {
      //do nothing
  }
}

hi, im following a tutorial on line, i have created this servlet class which is running on Apache Tomcat. When i run the class i get a blank screen without the json content, am i missing something theres nothing left on the tutorial or comment section, thanks?

2
  • what tutorial is it? Commented Jan 23, 2015 at 14:33
  • You're probably supposed to write the output string into the response Commented Jan 23, 2015 at 14:33

1 Answer 1

6

You need to write the content of your JSON object in the response stream. Here's how you can do it:

public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("application/json");
    String output = json.toString();
    PrintWriter writer = response.getWriter();
    writer.write(output);
    writer.close();
}

Also, it's a bad practice to declare non-final objects in your Servlet unless they're managed by the application server like EJBs or DataSources. I'm not sure which tutorial you're following but there are some issues with it:

  1. We're at Servlet 3.1, and a servlet can be decorated with @WebServlet rather than use configuration in web.xml.
  2. You should avoid declaring non-final fields in a Servlet due to concurrency problems. This can be noticed when the field is updated through a GET or POST call to the servlet and multiple (2 or more) clients perform the same call on the servlet at the same time, which will end in odd results for the clients of the servlet.
  3. If you want/need to obtain data to use in a Servlet, you should obtain it in the narrowest possible scope. In case of Servlets, this means that you should obtain the data in the one of the doXXX methods.

Here's how your code sample should look like:

@WebServlet("/path")
public class Test extends HttpServlet {
    //avoid declaring it here unless it's final
    //JSONObject json = new JSONObject();

    public void init() throws ServletException {
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        //check that now JSONObject was moved as local variable
        //for this method and it's initialized with the result
        //of a method called retrieveData
        //in this way, you gain several things:
        //1. Reusability: code won't be duplicated along multiple classes
        //   clients of this service
        //2. Maintainability: centralize how and from where you will
        //   retrieve the data.
        JSONObject json = retrieveData();

        response.setContentType("application/json");
        String output = json.toString();
        PrintWriter writer = response.getWriter();
        writer.write(output);
        writer.close();
    }

    //this method will be in charge to return the data you want/need
    //for learning purposes, you're hardcoding the data
    //in real world applications, you have to retrieve the data
    //from a datasource like a file or a database
    private JSONObject retrieveData() {
        //Initializing the object to return
        JSONObject json = new JSONObject();
        //filling the object with data
        //again, you're hardcoding it for learning/testing purposes
        //this method can be modified to obtain data from
        //an external resource
        json.put("city", "Mumbai");
        json.put("country", "India");
        //returning the object
        return json;
    }

    public void destroy() {
        //do nothing
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Just out of interest. Whats the difference between PrintWriter.write and print as well as close and flush?
@StefanBeike in a PrintWriter, the write method comes from super class Writer, and this class has print, printf and println methods are wrappers for write method (check the source code). Also, calling close already flushes all the content into the underlying stream automatically.
@LuiggiMendoza Hey I followed the code but the browser still not printing out anything. However, the json is actually printed out on the servlet console. I am using GlassFish by the way. Does that make a difference?
@2dollar20cents server and client are different. Looks like you've tested your server and works fine. Try using a simple client for your REST API like Postman and check if you get the results there. If yes, then probably there's an issue in your JavaScript code consuming this service.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.