如何从 Servlet 向 JSP 发送数据?

3

我正在开发一个项目,只有一个页面(index.jsp),在页面初始化时发送了一个Ajax请求并检索JSON数据。该AJAX调用发送到我的Servlet中,该Servlet返回JSON数据,而我只有一个Servlet。我试图将一些数据发送到我的JSP页面以实现填充,所以这就是我编写Servlet的方式......

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out =response.getWriter();
    String queryString = request.getQueryString();
            ResourceBundle props = ResourceBundle.getBundle("jira");

    XmlMerge xmlMerge = new XmlMerge();
    String mergeFiles=xmlMerge.getJsonData();

    out.println(mergeFiles);
    out.close();
         //Debug Statement
        System.out.println(xmlMerge.getTodo());
        // *THIS IS THE WAY I AM SEND DATA TO JSP PAGE.*
    request.setAttribute("todo", xmlMerge.getTodo());
    request.getRequestDispatcher("/index.jsp").forward(request, response);
}

在我的index.jsp页面中

<%=(String)request.getAttribute("todo")%>

我正在尝试输出结果。

出了什么问题吗?


2
你没有看到服务器日志中的那些IllegalStateException吗?这明显不是一个拦截转发到JSP请求的servlet应该有的样子。那个null很可能只是来自mergeFiles变量。当你最终需要在servlet中转发到JSP时,通常应该避免在servlet中使用response对象,因为此时响应将由JSP处理。 - BalusC
我执行了System.out.println并且它输出了正确的值"mergeFiles"。 - pushya
@BalusC 服务器日志中没有 IllegalStateExceptions。 - pushya
你能否更新问题的代码并添加调试语句?或者是XmlMerge源代码。 - porfiriopartida
显然,你调用它的方式是错误的,或者你没有运行你认为你正在运行的代码。奇怪的是,在servlet应该返回JSON数据的同时设置了text/html内容类型头。以下至少是一些链接,可以让你正确地开始:http://stackoverflow.com/tags/servlets/info 和 https://dev59.com/BW855IYBdhLWcg3w1oPa#4113258 - BalusC
显示剩余3条评论
1个回答

9
我刚刚执行了这个更改,它会显示您所需的内容:
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    request.setAttribute("todo", "10");
    request.getRequestDispatcher("/index.jsp").forward(request, response);
  }

这是生成的index.jsp:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

<%=(String)request.getAttribute("todo")%>

</body>
</html>

你的 getTodo() 可能存在问题,我不知道它的工作原理,但也许这可以帮助你:

...
XmlMerge xmlMerge = new XmlMerge();
String todo = xmlMerge.getTodo();
...
request.setAttribute("todo", todo);

更新:

PrintWriter out = response.getWriter();
out.println(...);
out.close();

这是你的问题... 你正在获取资源并关闭它。这可能会导致非法状态异常问题。
你“不需要”将dispatcher发送到index.jsp... 如果你不使用dispatcher但想呈现你的页面,你可以使用类似于这样的东西:
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    response.setContentType("text/html");
    response.getWriter().write("<html><body>"+getSomething()+"</body></html>");
  }

为什么index.jsp不是默认调用的页面?因为可能并不存在一个名为index.jsp的文件,而且它也可能是另一个servlet的调用。您可以配置将对index.jsp的调用映射到一个servlet。

http://tutorials.jenkov.com/java-servlets/web-xml.html

我仍然不知道使用out.println的目的,但如果你想在jsp中显示它,可以将其作为"todo"参数发送:
 request.setAttribute("mergeFiles", mergeFiles);

然后在jsp中将其打印为“todo”。

“request.getRequestDispatcher("/index.jsp").forward(request, response)” 的目的是什么?如果我只有一个 JSP 页面,那么它不会将数据发送到同一 JSP 页面吗?我需要编写调度程序语句吗? - pushya
@pushya事实上,你不需要一个index.jsp,因为它可能是你域名根目录的默认调用,但你可以在没有分派器的情况下显示HTML... 像这样:response.getWriter().write("<html><body>Not the index.jsp</body></html>");而且,由于您可以有映射,index.jsp可以是另一个servlet(而不是index.jsp文件),您可能不想调用它。 - porfiriopartida
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 这个对于 JSP 页面是必须的吗? - pushya
@pushya 我不认为是这样,这只是IDE的默认添加项,有时您需要根据要使用的标签/命令添加几行代码。我认为这并不是这种情况。 - porfiriopartida

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接