关于父子工程的理解:
<modules> <module>servlet-01</module> </modules>
<parent> <artifactId>JavaWeb_Servlet</artifactId> <groupId>com.zfy</groupId> <version>1.0-SNAPSHOT</version> </parent>
son extends father
对于初学者而言,步骤较为复杂,总而言之分为如下几步:
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency>
// 由于get或者post只是请求实现的不同方式,因此可以相互调用。二者的业务逻辑是一致的。 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ServletOutputStream outputStream = resp.getOutputStream(); PrintWriter writer = resp.getWriter(); // 响应流 writer.print("Hello,Servlet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); }
(一)Servlet总体原理
(二)Mapping问题
Mapping即路径映射,是提供一个访问Servlet程序的路径,其规则如下:
<servlet-mapping> <!-- servlet的内部名称,与上面的保持一致--> <servlet-name>hello</servlet-name> <!-- servlet的访问路径.hello/* ,*为通配符,代表*号位置的任意输入都可以访问到该映射 --> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
<servlet-mapping> <!-- servlet的内部名称,与上面的保持一致--> <servlet-name>hello</servlet-name> <!-- servlet的访问路径,*为通配符,.zfy为后缀。代表*号位置的任意输入+.zfy后缀都可以访问到该映射 --> <url-pattern>*.zfy</url-pattern> </servlet-mapping>
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,该对象代表了当前的web应用。
ServletContext对象是凌驾在所有Servlet程序之上的,同一个web应用的servlet程序共用同一个ServletContext对象。
在任意Servlet中保存的数据,通过Context对象,可以在另一个Servlet中拿到。
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // this.getInitParameter(); 初始化参数 // this.getServletConfig(); 初始化配置 // this.getServletContext(); 获取Context对象,即上下文对象。 // ①获取ServlContex对象 ServletContext context = this.getServletContext(); // ②创建一个Servlet02中的对象(数据) String username = "青梧成林"; // ③将该数据保存在了ServlContex对象中,以键值对的形式保存。 context.setAttribute("username", username); System.out.println("Hello!"); } }
public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ①获取Context对象 ServletContext context = this.getServletContext(); // ②将另一个servlet程序保存在Context对象中的键值对取出,这里输入键名即可。 // 键值对中保存的是object类型,将其强转为String对象。 String username = (String) context.getAttribute("username"); // ③将取到的值在网页上输出 resp.setContentType("text/html"); // 设置文本格式 resp.setCharacterEncoding("utf-8"); // 设置中文编码格式 resp.getWriter().print("username: " + username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
给两个Servlet文件配置相关映射路径:
测试.先访问Servlet1文件,再访问Servlet2文件:
<!-- 配置一些web应用初始化参数 --> <!-- 数据库框架连接参数 --> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
public class ServletDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); // 获得web初始化参数,这是配置在web.xml里面的 System.out.println("url: " + url); // Sout输出只能在idea后台给出,无法在网页中输出。 resp.getWriter().print(url); // resp对象的getWriter()方法获取网页输出对象,再用print()方法打出。 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
(1)请求转发:
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); // 请求转发分成两步来写 // RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); // 转发的请求路径 // requestDispatcher.forward(req, resp); // 调用forward实现请求转发 //合成一步来写: context.getRequestDispatcher("/gp").forward(req,resp); }
public class ServletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ①流通过资源地址获取properties对象 InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classer/db.properties"); // ②将资源读出,赋予对象 Properties prop = new Properties(); prop.load(is); String user = prop.getProperty("username"); String pwd = prop.getProperty("password"); // ③在网页上写出 resp.getWriter().print("username: " + user +", " + "password: " + pwd); }
问题描述:发布在tomcat上后,子工程的target中文件夹内仅有war文件,其余文件均缺失,而父工程中的target中会出现classes文件夹,其中包含有对应的class文件。
排错1:让子工程中的target中出现正常的文件夹分布。
解决办法:
在tomcat配置中找Before launch,把里面的全删除,然后加号选择Run Maven Goal ,目录选择父文件目录,命令为:clean packgae,之后重启tomcat
此步之后子工程target文件分布正常:
排错2:
此时index.jsp可以正常访问,但是servlet跳转依旧提示错误404.原因为WEB-INF中没有lib文件夹,即子工程中jar包未能发布到tomcat上。
经过查找,在父工程的pom中,对添加依赖的jar包添加了scope标签,导致子工程在发布到tomcat时无法获取到父工程中jar包的信息。
解决办法:
将父项目pom.xml中依赖的
<!-- <scope>provided</scope> --> <!-- 设置作用域为provided,表明该包旨在编译和测试时使用,会导致子工程发布到tomcat时无法获取父工程jar包信息。-->
参考链接:https://blog.csdn.net/x2027290/article/details/118718710