【问题标题】:JSON output showing on Java Servlet显示在 Java Servlet 上的 JSON 输出
【发布时间】:2015-03-22 14:54:42
【问题描述】:
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
  }
}

嗨,我正在按照在线教程进行操作,我创建了这个在 Apache Tomcat 上运行的 servlet 类。当我运行课程时,我得到一个没有 json 内容的空白屏幕,我是否遗漏了一些东西,教程或评论部分什么都没有了,谢谢?

【问题讨论】:

  • 教程是什么?
  • 您可能应该将output 字符串写入response

标签: java json servlets


【解决方案1】:

您需要在响应流中写入 JSON 对象的内容。你可以这样做:

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

此外,在 Servlet 中声明非最终对象是一种不好的做法,除非它们由应用程序服务器(如 EJB 或数据源)管理。我不确定您正在遵循哪个教程,但它存在一些问题:

  1. 我们使用的是 Servlet 3.1,可以使用 @WebServlet 装饰 servlet,而不是使用 web.xml 中的配置。
  2. 由于并发问题,您应该避免在 Servlet 中声明非最终字段。当通过对 servlet 的 GET 或 POST 调用更新字段并且多个(2 个或更多)客户端同时在 servlet 上执行相同的调用时,可以注意到这一点,这对于 servlet 的客户端将以奇怪的结果结束.
  3. 如果您想要/需要获取在 Servlet 中使用的数据,您应该在尽可能窄的范围内获取它。对于 Servlet,这意味着您应该在 doXXX 方法之一中获取数据。

您的代码示例应如下所示:

@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
    }
}

【讨论】:

  • 只是出于兴趣。 PrintWriter.write 和 print 以及 close 和 flush 有什么区别?
  • @StefanBeike 在PrintWriter 中,write 方法来自超类Writer,并且这个类有printprintfprintln 方法是@987654331 的包装器@ 方法(查看源代码)。此外,调用close 已经自动将所有内容刷新到底层流中。
  • @LuiggiMendoza 嘿,我按照代码进行了操作,但浏览器仍然没有打印出任何内容。但是,json 实际上是在 servlet 控制台上打印出来的。顺便说一句,我正在使用 GlassFish。这有什么不同吗?
  • @2dollar20cents 服务器和客户端不同。看起来你已经测试了你的服务器并且工作正常。尝试为你的 REST API 使用一个简单的客户端,比如 Postman,并检查你是否在那里得到了结果。如果是,那么您的 JavaScript 代码使用此服务可能存在问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
相关资源
最近更新 更多