我想记录我的网络应用中任何资源的访问次数: 这是我的班级:
public class FullTracking extends HttpServlet
{
Hashtable<String,Integer> links=new Hashtable<>();
public void doGet(HttpServletRequest req,HttpServletResponse res) throws
ServletException,IOException{
String uri=req.getRequestURI();
String resource=uri.substring(req.getContextPath().length(),uri.length());
if(links.containsKey(resource)){
Integer count=links.get(resource);
links.put(resource,new Integer(1+count.intValue()));
}
else{
links.put(resource,new Integer(1));
}
req.setAttribute("links",links);
req.getRequestDispatcher("/FullTracking.jsp").forward(req,res);
}
public void doPost(HttpServletRequest req,HttpServletResponse res) throws
ServletException,IOException{
doGet(req,res);
}
}
FullTracking.jsp:
<%@ page import="com.tests.FullTracking,java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
key/value pairs:<br/>
<c:forEach var="r" items="${links}">
${r.key}:${r.value}<br/>
</c:forEach>
的web.xml:
<servlet>
<servlet-name>FullTracking</servlet-name>
<servlet-class>com.tests.FullTracking</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FullTracking</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
如果我使用当前映射访问任何资源,我会收到Inernal服务器错误(500),以及由
引起的java.lang.StackOverflowError根本原因结束的冗长堆栈跟踪req.getRequestDispatcher("/FullTracking.jsp").forward(req,res);
如果我将web.xml中的映射更改为:
<servlet-mapping>
<servlet-name>FullTracking</servlet-name>
<url-pattern>/tracker/*</url-pattern>
</servet-mapping>
没有错误,但结果不是我所期望的。 出于学习目的:我想了解调度和java.lang.StackOverflowError之间的联系。
Type Exception Report
Message Servlet execution threw an exception
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Servlet execution threw an exception
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
com.tests.FullTracking.doGet(FullTracking.java:24)
javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
Root Cause
java.lang.StackOverflowError
javax.servlet.http.HttpServletRequestWrapper.getMethod(HttpServletRequestWrapper.java:123)
javax.servlet.http.HttpServletRequestWrapper.getMethod(HttpServletRequestWrapper.java:123)
javax.servlet.http.HttpServlet.service(HttpServlet.java:628)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
com.tests.FullTracking.doGet(FullTracking.java:24)
javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
com.tests.FullTracking.doGet(FullTracking.java:24)
提前致谢
编辑:
我理解java.lang.StackOverflowError
的来源。事实上,由于映射,servlet捕获了请求,然后从调度程序内部通过相同的映射转发到jsp,这又被servlet捕获,依此类推。
我现在的问题是如何告诉调度员在转发到JSP时不要通过映射?
答案 0 :(得分:0)
这可能是因为Dispatcher正在错误的地方寻找JSP。
根据您提供的信息,我可以找出您的servlet的URL,就像您更新了web.xml一样:
http://localhost:8080/<rootContext>/tracker
现在,req.getRequestDispatcher("/FullTracking.jsp").forward(req,res);
会在http://localhost:8080/<rootContext>/
中查找jsp。
确保jsp存在于此位置。
因为,就你的问题而言,这不会给你准确的计数,因为你的程序是不 ThreadSafe
锁定你的地图,这样一次只有一个人可以访问它/ p>
private Hashtable<String,AtomicInteger> links=new Hashtable<>();
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String uri = req.getRequestURI();
String resource = uri.substring(req.getContextPath().length(), uri.length());
synchronized (links) {
if (links.containsKey(resource)) {
AtomicInteger count = links.get(resource).incrementAndGet();
links.put(resource, count);
} else {
links.put(resource, new AtomicInteger(1));
}
}
req.setAttribute("links", links);
req.getRequestDispatcher("/FullTracking.jsp").forward(req, res);
}