获取类路径下的资源

  对于一个web项目来说,类路径就是class目录,我们可以使用Class类的对象,来获取类路径下的资源,这在加载一些配置文件时,使用得到 

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream resourceAsStream = this.getClass().getResourceAsStream("/a.txt");
        Scanner scanner = new Scanner(resourceAsStream);
        while (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
    }
}

  需要注意的是我们在使用 getResourceAsStream("/a.txt");方法时,在文件名前添加了一个“/”符,这表示我们获取的时根目录下的资源,即/classes目录

  如果我们不加“/”符呢,我们发现服务器给浏览器发送了一个500的状态码,这表示服务器端发生了错误,因为不加“/”相当于在HelloServlet.class同目录下获取资源,然而这个目录没有a.txt,所以也就获取不到这个资源了。

  总结:如果加“/”,getResourceAsStream方法的相对目录是/classes目录,如果不加“/”,方法的相对目录是当前调用这个方法的Servlet的class文件所在的目录

 

  我们还可以使用Classloader类获取类路径下的资源

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     // 这里加不加“/”得到的结果都是一样的 InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("/a.txt"); Scanner scanner = new Scanner(resourceAsStream); while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); } } }

  总结:对于Classloader来说加不加“/”都是相当于/classes目录

 

请求转发和请求包含

  当服务器调用某个Servlet的service方法来完成对客户端的请求时,这个Servlet可以将请求转发到其他的Servlet中,两个Servlet合作共同完成对客户端的响应,代码如下:

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/AServlet").forward(req, resp);
    }
}
public class AServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        response.getWriter().print("Hello!");
    }
}

  在HelloServlet中,我们将请求转发到了AServlet,AServlet对请求做出相应,使用HttpServletRequest 的getRequestDispatcher("要转发的Servlet的路径"),可以得到一个转发器,然后根据实际情况使用forward或者include方法,这两个Servlet使用的是同一个HttpServletRequest 和同一个HttpServletResponse对象,所以能够对同一个请求做出相应。

  请求转发:发出转发请求的Servlet可以设置响应头,但是不能设置响应体

  请求包含:两个Servlet都可以设置响应头和体

 

重定向和转发的区别

  • 客户端发出请求,然后服务器给出一个重定向的响应,服务器会根据响应中的Location头,再次发出一个请求,URL就是Location头的值
  • 客户端发出请求,服务接收到请求,调用某个Servlet的service方法,然后Servlet将请求转发给了另一个Servlet,共同完成响应,最后响应给客户端,
  • 浏览器是不知道发生的请求转发的,转发完成之后,方法的调用会回到转发处,然后继续执行接下来的方法,
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/AServlet").forward(req, resp);
        System.out.println("a"); // 将在控制台输出a
    }
}

  转发完成之后,会继续回到doGet方法中,执行剩下的代码,

 

posted on 2018-10-07 21:34  yusiming  阅读(179)  评论(0)    收藏  举报