获取类路径下的资源
对于一个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方法中,执行剩下的代码,
浙公网安备 33010602011771号