我正在尝试这个小HttpSession
程序作为我项目的演示
该程序只检查用户是否是新用户,如果用户是新用户,则显示form
,如果用户不是新用户,则显示用户名,他选择的color
以及总数为。访问。
当我运行我的程序时,它仅适用于第一次。这意味着当我运行我的程序的另一个实例时,它会显示一个空白的网页。
导致此问题的代码有什么问题?
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
Integer hitCount;
HttpSession s = request.getSession(true);
if(s.isNew()) {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SessionServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<form method=get action=SessionServlet>");
out.println("<h3>Please sleect a Color</h3>");
out.println("<input type=radio name=color />Red");
out.println("<br /><input type=radio name=color />Green");
out.println("<br /><input type=text name=txtName />");
out.println("<br /><input type=submit name=Submit value=Submit />");
out.println("</form>");
out.println("</body>");
out.println("</html>");
} else if(!s.isNew()){
String name = (String) request.getParameter("txtName");
String color = (String) request.getParameter("color");
hitCount = new Integer(1);
s.setAttribute("Name", name);
s.setAttribute("color", color);
s.setAttribute("HitCount", hitCount);
if((name != null) && (color != null)) {
out.println("Name: " + s.getAttribute("Name"));
hitCount = (Integer)s.getAttribute("HitCount");
hitCount = hitCount++;
s.setAttribute("HitCount", hitCount);
//out.println("<body bgcolor=" + s.getAttribute("color") + ">");
out.println("you selected" + s.getAttribute("color"));
out.println("Total visits=====>" + s.getAttribute("HitCount"));
}
}
}
}
}
答案 0 :(得分:2)
第二次运行此代码时,会话已经存在,因此程序会通过 else 分支 - 但“旧”请求对象(来自应用程序的第一次运行)及其参数(颜色和名称)在那时已经消失。在第一次应用程序运行的响应被发送回客户端后,请求被容器销毁。
在您的代码中
String name = (String) request.getParameter("txtName");
String color = (String) request.getParameter("color");
您正在尝试获取不存在的参数。参数 txtName 和 color 不再存在于 request 中。因此它们是null并且是下一个条件
if((name != null) && (color != null))
总是 false 。并且没有任何内容写入 out Writer。
为了完成这项工作,您应该做的是从会话对象中读取参数(这是会话的目的),您应该将它们放在第一个应用程序运行中。此代码无效。您的 hitCount 将始终为1(请参阅 HttpSessionListener 界面)。这个代码在很多层面都是错误的 - 你应该在else if
分支之后重新编写所有内容,而这个分支应该只有else
。
TLDR: 你的问题是为什么它不起作用:答案是 - 你正在阅读不存在的参数。您必须在第一个应用程序运行中将参数放入 session 对象并从中读取它们。
这是我要做的。假设这个名为 SessionServlet 的简单项目的目录结构如下。这个结构将用于整个答案。为了简化事情,我不会列出每个目录,你肯定会从中得到这个想法。这是不目录结构的真实示例,为了本教程示例的目的,它被简化。
<path-to-project>/SessionServlet/src/com/example/session
<path-to-project>/SessionServlet/WebContent/META-INF
<path-to-project>/SessionServlet/WebContent/WEB-INF
创建 html 文件,例如 start.html 。它应包含您需要在会话中存储的值的输入字段。文件在这里
<path-to-project>/SessionServlet/WebContent/start.html
其内容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Start page</title>
</head>
<body>
<form method="get" action="MySessionServlet">
<h3>Please select a Color</h3>
<input type="radio" name="color" value="red" />Red<br>
<input type="radio" name="color" value="green" />Green<br>
<input type="text" name="txtName" /><br>
<input type="submit" name="Submit" value="Submit" />
</form>
</body>
</html>
在你的servlet示例中,你忘记了radiobutton输入中的 value 属性,因此无论你要检查哪个radiobutton,值都是 on ,而不是颜色名称。
接下来,您必须创建servlet类 SessionServlet.java ,这与您最初的想法略有不同。它在这里:
<path-to-project>/SessionServlet/src/com/example/session/SessionServlet.java
其内容
package com.example.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet {
private static final long serialVersionUID = -3808675281434686897L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String requestColor = null;
String requestTxtName = null;
PrintWriter out = response.getWriter();
MySessionListener listener = new MySessionListener();
HttpSession session = request.getSession();
if (session.isNew()) {
//these are request parameters sent from html form
requestColor = request.getParameter("color");
requestTxtName = request.getParameter("txtName");
//save the attributes in session in order to use them later
session.setAttribute("sessionColor", requestColor);
session.setAttribute("sessionTxtName", requestTxtName);
}
else {
//get the previously stored attributes from session
String color = (String) session.getAttribute("sessionColor");
String name = (String) session.getAttribute("sessionTxtName");
//session info
out.println("session already existed");
if (color != null && name != null) {
out.println("Name: " + name);
out.println("Color: " + color);
out.println("Session count: " + listener.getSessionCount());
}
}
}
}
我认为servlet的代码几乎是不言自明的。但是,如果您有任何特殊问题,请询问。
为了计算活动会话,您需要创建一个SessionListener类并计算会话数。出于本示例的目的,我将该类放入与servlet类相同的目录中。请不要在实际项目中这样做。你会制造一个大混乱。这只是简化的Java Enterprise Hello world 示例。该文件在这里
<path-to-project>/SessionServlet/src/com/example/session/MySessionListener.java
其内容为
package com.example.session;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MySessionListener implements HttpSessionListener {
private static int sessionCount;
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("Creating session with id: " + se.getSession().getId());
sessionCount++;
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("Destroying session id: " + se.getSession().getId());
sessionCount--;
}
public int getSessionCount() {
return sessionCount;
}
}
用于计算活动会话的侦听器类必须实现 HttpSessionListener 接口。我们在SessionServlet类中调用了方法 getSessionCount(),正如您已经注意到的那样。
最后要做的是创建一个部署描述符xml,以告诉容器如何处理我们创建的类。 文件必须命名为web.xml,必须放在WEB-INF目录中。
<path-to-project>/SessionServlet/WebContent/WEB-INF/web.xml
其内容为
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID"
version="3.1">
<display-name>SessionServlet</display-name>
<welcome-file-list>
<welcome-file>start.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>my Session Servlet</servlet-name>
<servlet-class>com.example.session.SessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>my Session Servlet</servlet-name>
<url-pattern>/MySessionServlet</url-pattern>
</servlet-mapping>
<!-- set session timeout to 30 minutes -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- register listener class -->
<listener>
<listener-class>com.example.session.MySessionListener</listener-class>
</listener>
</web-app>
就是这样。最后我的两分钱 - 你应该首先熟悉标准版Java。这是来自企业界的一个例子。网上有很多教程。给它一些时间,你不会后悔的。
关于servlet-在开始创建实际项目之前,您应该(必须)首先了解请求,响应,会话,客户端和容器(谁是谁,生命周期,管理等)的基本概念。我见过的最好的书是Head First - Servlets和JSP,它应该是理解这个主题的起点。
答案 1 :(得分:1)
您设置response.setContentType("text/html;charset=UTF-8")
....
但在您的if(!s.isNew()){....
部分中,输出不是HTML,而是纯文本。 (“Name:
”等等......)
我敢打赌,内容已存在,但您的浏览器未显示内容。