我试图为每个会话的获取请求制作一个计数器,但我终于做到了,但是,我有一个问题,以便了解逻辑的底部是如何工作的。这是我的代码:
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
final String COUNTER = "Counter";
/**
* @see HttpServlet#HttpServlet()
*/
public FirstServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
PrintWriter out = resp.getWriter();
int count = 1;
Integer i = (Integer) session.getAttribute(COUNTER);
if(i != null){
count = i.intValue() +1;
}
session.setAttribute(COUNTER, new Integer(count));
out.println("<html>");
out.println("<head>");
out.println("<title>Session Counter</title>");
out.println("</head>");
out.println("<body>");
out.println("Your session ID is <b>" + session.getId());
out.println("</b> and you have hit this page <b>" + count
+ "</b> time(s) during this browser session");
}
以下是问题:
Integer i = (Integer) session.getAttribute(COUNTER);
if(i != null){
count = i.intValue() +1;
}
由于我正在制作Integer i然后将其转换为整数,这是否意味着无论String值如何,它的int值始终为0? (因为COUNTER的类型为String)
我的第二个问题是:为什么在得到它之后我必须使用session.setAttribute()来打印新值。我的逻辑如下。我们知道每个servlet只被实例化一次 - 我得到属性(session.getAttribute(COUNTER)),检查我是否不同于null然后递增它,如果我评论setAttribute我将无法看到新增值。为什么我必须再次设置以获得正确的值?当我按下刷新时,我发出一个新的获取请求并且它取旧的COUNTER值(例如2),然后我们检查它是否为空并将其递增1.我不明白为什么我必须再次使用session.setAttribute ...
谢谢!
答案 0 :(得分:1)
第一个问题:
如果该属性不在会话中,i
将为null
。
第二: 此行为与 immutability 的概念和理解Java references 的概念有关。
由于会话正在存储对象,因此counter
将通过自动装箱成为Integer
对象的引用(因此无需手动创建Integer
)。它是JDK中的 immutable 类之一,要更改其值,您需要创建一个新对象reference
,这就是为什么需要更新对象的原因存储在会话中 - 因为会话仍将参考地址存储为旧值。