从一个Servlet传递值到另一个Servlet

3

我正在尝试将一个Servlet中的值传递到另一个Servlet中,但是我已经尝试了各种方法,但它总是为空。 我正在尝试获取“删除任务”旁边的“id”。 我已经尝试将其存储在会话中,尝试使用request.getParameter。 有什么建议吗?

try{
        int id = DataAccess.getUserID(name);
        list = DataAccess.displayTasks(id);
    }
    catch(Exception e){e.printStackTrace();}

out.println(OurUtils.getHeader("List of Tasks"));
    out.println("<center><h2>List of Your Tasks</h2>");
    out.println("<table>");
    for (Tasks T : list){
        out.println("<tr>");
        out.println("<td><a href = \"DeleteTask?id="+T.getId()+"\">Delete</a></td>");
        out.println("<td><a href = \"ModifyTask?id="+T.getId()+"\">Modify</a></td>");
        out.println("<td>"+T.getTask()+"</td></tr>");
    }
    out.println("</table>");
    out.println("");
    out.println("<a href=\"AddTask\">Add a new task</a>");
    out.println("</center>");
    out.println(OurUtils.getFooter());

这是我的显示任务方法。
public static ArrayList<Tasks> displayTasks(int id) throws ClassNotFoundException, 
IllegalAccessException, InstantiationException,SQLException{
Class.forName(driver).newInstance();
con = DriverManager.getConnection(url,sqluser,sqlpass);
st = con.createStatement();
String sql = "SELECT task from Assignment2Tasks where userID = "+id+"";
ResultSet rs = st.executeQuery(sql);

ArrayList<Tasks> list = new ArrayList<Tasks>();

while(rs.next()){
    Tasks T = new Tasks(rs.getString(1));
    list.add(T);
}

con.close();
return list;

这段代码中涉及到了 list,它是怎么来的? - Victor Sorokin
我在我的帖子中编辑了它。 - Craig
找不到任何问题。请提供其他的servlets和displayTasks方法。 - Leo
“name” 是来自客户端 HTTP 请求的吗?也许,在您的数据提供程序中没有这样的 “name”,因此 “list” 是空的?另一个选项是,由于某种原因,“DataAccess” 没有正常工作。 - Victor Sorokin
你为什么要手写HTML打印语句,而不使用类似Spring MVC或至少JSP这样的东西呢? - chrylis -cautiouslyoptimistic-
我仍在学习,这是我迄今为止学会如何做的方式。 - Craig
5个回答

2

也许您已经知道,这是如何在Servlet间共享您的服务对象(例如DAO对象)和域对象(任务列表):

  1. In your web.xml you define listener object, implementing ServletContextListener, so listener will be called once application is deployed into Servlet container (jetty, tomcat):

     <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
        <servlet>
            <servlet-name>Main</servlet-name>
            <servlet-class>vic.web.MainServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <listener>
            <listener-class>vic.web.AppInitializationListener</listener-class>
        </listener>
    
        <servlet-mapping>
            <servlet-name>Main</servlet-name>
            <url-pattern>/main</url-pattern>
        </servlet-mapping>
    
    </web-app>
    
  2. In code of that listener you initialize your data layer and put reference to it inside ServletContext, which is guaranteed to be shared across all servlets of your webapp, which are run in the same JVM:

    public class AppInitializationListener implements ServletContextListener {
    
        private static final Logger logger = LoggerFactory.getLogger(MainServlet.class);
    
        static final String INITIAL_TASKS_KEY = "INITIAL_TASKS_KEY";
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            logger.info("Application initialization commences...");
            sce.getServletContext().setAttribute(INITIAL_TASKS_KEY,
                    new TasksList(Arrays.asList("From me to you", "We can work it out", "Long and winding road")
                    ));
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
        }
    }
    
  3. In code of your servlet(s), you override init(ServletConfig config) method which is called by container once servlet is initialized. There, you reach out for data initialized in listener and here you go!

    public class MainServlet extends HttpServlet {
    
        private static final Logger logger = LoggerFactory.getLogger(MainServlet.class);
    
        private TasksList initialTasks;
    
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
    
            logger.info("Here");
    
            ServletContext ctx = getServletContext();
            //noinspection unchecked
            initialTasks = (TasksList) ctx.getAttribute(AppInitializationListener.INITIAL_TASKS_KEY);
    
            logger.info("Got: " + initialTasks);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            PrintWriter writer = resp.getWriter();
            StringBuilder sb = new StringBuilder("<html><body>Hello there. Here are your tasks:<br><ol><br>\n");
            for (String task : initialTasks.getTasks()) {
                sb.append("<li>").append(task).append("</li><br>\n");
            }
            sb.append("</ol>\n</body></html>");
            writer.write(sb.toString());
            writer.flush();
            writer.close();
        }
    
    }
    
  4. Here data layer is just POJO containing static list of tasks. Since you want to get data from DB (naturally), you should put your JDBC initialization code in listener as shown above and make listener put obtained DriverManager into context.

  5. Okay, but in reality you will want to change these things: a) use some MVC framework instead of creating HTML by hand; b) Use DataSource and pool of JDBC connections instead of DriverManager


1
我不知道为什么你使用了那么多的out.println而不是至少使用jsp。我已经在jsp中完成了这个过程。
我的servlet列表
List<User> list = userService.viewUser();    //userService is used to access the data from db by calling the daoservice
request.setAttribute("list",list);
rs=request.getRequestDispatcher("manageuser.jsp");
rs.include(request,response);

这是我的JSP代码,请注意所有数据都在表格标签内。
<%List list=(List)request.getAttribute("list");%>   //Getting the list attributes from the appropriate servlet
<c:forEach items="${list}" var="user">      //for each loop
<tr>
    <td><c:out value="${user.userId}" /></td>
    <td><c:out value="${user.userName}" /></td>
    <td><c:out value="${user.emailId}" /></td>
    <td><a href="menuaction?redirectValue=edituser&Id=${user.userId}">Edit</a>
    <a href="menuaction?redirectValue=deleteuser&Id=${user.userId}">Delete</a></td>
</tr>
</c:forEach>

然后在我执行删除操作和编辑操作的servlet中(对于您来说只是删除操作)

int id = Integer.parseInt(request.getParameter("Id")); //Do the appropriate actions from this id variable

我还不知道如何使用JSP。 - Craig
@Kalkrin 这个替代方案解释了你如何去做,而且你应该这么做。我不知道你正在使用哪些资源来学习Servlets,但是似乎很糟糕,因为从Servlet直接编写HTML是一个坏习惯。 - Luiggi Mendoza
哦!现在我知道你为什么使用out.println了。在我学习阶段,我没有在servlet中做这么多的东西,我转向jsp了。让我在servlet中试试,也许明天我就能得到答案。 - user562

0

Servlet间通信: RequestDispatcher对象可以将客户端请求转发到资源(Servelt/Jsp)。 这里您希望Servlet_A调用Servlet_B。使用

RequestDispatcher dispatcher = getRequestDispatcher("Servlet_B");
   dispatcher.forward( request, response );

要在Servlet实例之间传递数据,您不需要转发。 - Victor Sorokin

0
<a href = \DeleteTask?id = 15>Delete</a>

当用户点击删除时,您可以通过request.getParameter("id")获取id,然后可以使用request将id传递给其他servlet。

另外,您还可以将其存储在会话中并获取它。

request.getSession(true).setAttribute("name",'AAAA');

request.getSession().getAttribute("name");

字符串 id; id = request.getParameter("id"); 如果(id == null) id = "-1"; 尝试{ DataAccess.deleteTask(Integer.parseInt(id)); }catch(Exception e){e.printStackTrace();} response.sendRedirect("DisplayTasks"); - Craig
不错,但你能否从浏览器检查该ID是否具有值。 按F12并搜索元素。 另外,“\DeleteTask”路径的Servlet映射是什么? - Gurkan İlleez
我的get参数不起作用,但在我之前做的一个类似程序中它是有效的。 - Craig

0
我已经找到了解决问题的方法。在我的DisplayTasks方法中,我只是提取任务的字符串并将其放入t对象中,而没有从表中提取ID。我无法将ID传递给其他servlet,因为它是一个空变量。

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