从servlet调度到jsp时出现服务器错误

时间:2018-05-18 08:41:25

标签: jsp servlets

我想记录我的网络应用中任何资源的访问次数: 这是我的班级:

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时不要通过映射?

1 个答案:

答案 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);
    }