ServletContext的应用(其二)★★★
请求转发
其实就是用想用的页面展示另一个页面的内容
例如练习:用 http://localhost:8080/servlet-002/sd4
网页展示http://localhost:8080/servlet-002/gp
页面的内容
代码
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了ServletDemo04");
//RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
//requestDispatcher.forward(req,resp); //调用forward实现请求转发;
context.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.xy.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
测试结果如下图
下面两图证明了我们用servletdemo04程序展示了servletdemo03程序的内容
图解请求转发(一次请求)
如上图所示:A(网页)想访问到C(/gp)的内容,但A不能直接向C要数据,那么就可以通过中介B(/sd4)来与C接触;
C把数据给B,B再把这份数据给A。这个过程就是请求转发的大致原理
在这整个过程中A是没有和C直接接触的,所以请求路径不变(http://localhost:8080/servlet-002/sd4
)
图解重定向(两次请求)
如上图所示:A想访问C的内容,它先问B有没有它想要的内容,B说我没有,但是C有;
A得到这个讯息以后,就直接向C发送访问请求
在这个过程中A是有和C直接接触的,所以请求路径会发生改变(http://localhost:8080/servlet-002/gp
)
读取资源文件(疑问已解决)
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:
思路:需要一个文件流
测试代码servletdemo05
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String user = properties.getProperty("username");
String pwd = properties.getProperty("password");
resp.getWriter().print("username:"+user);
resp.getWriter().print("password:"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml代码
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>com.xy.servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
properties代码
username=xy
password=123456
测试结果
如下图所示成功读取properties文件内容
在这次的学习中遇到了两个问题(已解决)
问题一是target目录不全
解决方式如下
第一步:改该子项目的pom文件 [跳转](##5.9 pom 文件) (## 5.9 pom 文件中有讲过打包不全的解决方案)
<!--在pom.xml的<build>中配置<resources>,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
第二步:clean清除该maven项目的打包内容,然后package
做完上边这些后,target文件夹目录就齐全了,如下图
另一个问题是资源读取路径问题
需要注意的是ServletDemo5代码中的这一行代码
this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
这说明了获取资源并转换为流这一命令读取的资源所在位置是打包完以后的target文件夹,也就是说读取的是经过打包以后的target文件夹中的资源文件db.properties
由下图可以很容易得分析出资源读取路径为 /WEB-INF/classes/db.properties
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律