JavaWeb02
2022/7/1 14:21:58
本文主要是介绍JavaWeb02,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
6. Servlet
6.1 Servlet简介
- Servlet是sun公司开发动态web的一门技术。
- Sun在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
- 编写一个类,实现Servlet接口。
- 把开发好的Java类部署到Web服务器中。
- Servlet项目由一个父项目和众多子项目构成,servlet接口在子项目中实现。
6.2 父项目与子项目
关于父子工程的理解:
- 父项目的配置文件中存在如下标签,记录了子项目的个数:
<modules> <module>servlet-01</module> </modules>
- 相对应的,子项目中存在如下标签,记录了父项目的情况:
<parent> <artifactId>JavaWeb_Servlet</artifactId> <groupId>com.zfy</groupId> <version>1.0-SNAPSHOT</version> </parent>
- 父项目中的java,子项目可以直接使用(继承与多态)
son extends father
- Servlet接口于子项目中实现。
6.3 Hello Servlet
对于初学者而言,步骤较为复杂,总而言之分为如下几步:
- 创建父工程
- 创建子工程
- 编写一个servlet程序,即在子工程中实现servlet接口
- 配置服务器,启动servlet。
6.3.1 父工程的创建
- 构建一个普通Maven项目(即不启用Maven模板。详细参考如上节所示)
- 删除src文件夹,其余不可删。
- 所得到的空工程即为Maven父工程(也称作主工程),可以在此创建众多子工程(即Module)。
- 在父工程中导入需要父/子工程需要的依赖,根据需求查询有哪些依赖需要导入。
以JSP工程为例,在父工程的pom.xml文件中导入如下依赖:
<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>
- 至此,父工程创建完毕。
6.3.2 子工程的创建
- 在父工程文件夹处new一个module
- 子项目启用Maven模板创建。
- 如图,此处创建的servlet项目为子项目,父项目就是原项目。
- 重写子项目web.xml文件,将其改成最新的服务器配置:
该步骤内容查询自:Tomcat-conf-web.xml,复制粘贴即可。
- 在main文件夹下创建:java文件夹和resource文件夹,并标记。以此补子全项目结构(main下面有三个文件夹才算结构齐全)。
- 至此,子工程创建完毕。
6.3.3 在子工程中创建servlet程序
- servlet是一个接口程序,也就是一个java程序,其存放于main-java文件夹中。
- servlet接口在sun公司有两个默认的实现类:①HttpServlet,②GenericServlet
- 在(子项目)java文件中new一个package,并在该package下新建一个class。
- 继承HttpServlet类,基于此类实现servlet接口,编写servlet程序。这是通过方法重载实现的。
(servlet相关class关系说明图)
- ctrl+o呼出接口与方法菜单,写入需要重载的方法(继承自HttpServlet)。
- 重载的方法原始代码如下:
- 方法重载(以Get和Post为例):
// 由于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); }
- 在子项目网页配置文件web.xml中编写Servlet映射
为什么需要映射?
我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器。
所以我们需要:- 在web服务器中注册我们的Servlet程序(class类)。
- 提供一个浏览器可以访问的路径(mapping映射)
- 至此,子项目servlet程序创立完毕。
6.3.4 配置Tomcat服务
- Tomcat配置过程如3.4节所述
- 启动测试:右上角运行Tomcat9服务器。
- Tomcat编译之后产生target文件夹,内容如图所示:
(生成的target文件夹可以通过Maven-lifecycle-clean清除)
- 弹出Tomcat默认的js界面:Hello World!
- 输入我们设置的servlet映射地址,即可访问到我们编写的servlet class文件。
- 发布并访问一个简单的servlet程序到此结束
6.4 Servlet原理
(一)Servlet总体原理
- 典型的Servlet业务流程如下所示:
- 其中我们自己编写的实现类重构service方法。
(二)Mapping问题
Mapping即路径映射,是提供一个访问Servlet程序的路径,其规则如下:
- 一个Servlet程序可以指定任意个映射路径(一个或者多个)
- 一个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>
6.5 ServletContext(对象)
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,该对象代表了当前的web应用。
ServletContext对象是凌驾在所有Servlet程序之上的,同一个web应用的servlet程序共用同一个ServletContext对象。
6.5.1 Context对象实现数据共享
在任意Servlet中保存的数据,通过Context对象,可以在另一个Servlet中拿到。
- 在第一个Servlet文件中,通过在ServletContext对象中创建键值对保存信息:
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!"); } }
- 在另一个Servlet文件中取出刚才保存的信息:
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文件:
6.5.2 Context对象获取初始化参数
- web.xml中可能存在一些网页初始化所需要的参数:
<!-- 配置一些web应用初始化参数 --> <!-- 数据库框架连接参数 --> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
- 使用ServletContext对象获取初始化参数
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); } }
- 注册Servlet,并测试访问。
网页测试结果,顺利拿到了初始化参数url:
6.5.2 Context对象请求转发
(1)请求转发:
- 访问A网页,A网页将请求转发到C网页。结果:路径为A,实际访问页面为C(即A拿到了C)。
- 请求转发的状态码为:200
(2)重定向: - 访问A,A刷新路径为C,改为访问C。访问路径发生改变。
请求转发的实现:
- 编写Servlet程序,context.getRequestDispatcher 实现转发
@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); }
- 网页测试
6.5.2 Context对象读取资源文件
- main-resource文件夹下新建配置文件,命名为db.properties:
- 创建Servlet程序.通过编译后的资源地址获取Properties资源:
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); }
- web注册并测试:
成功拿到资源:
6.6 HttpServletResponse对象
Z. 本章遇到的错误
1. MAVEN子工程发布在tomcat上时没有lib文件夹
问题描述:发布在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
这篇关于JavaWeb02的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24怎么修改Kafka的JVM参数?-icode9专业技术文章分享
- 2024-12-23线下车企门店如何实现线上线下融合?
- 2024-12-23鸿蒙Next ArkTS编程规范总结
- 2024-12-23物流团队冬至高效运转,哪款办公软件可助力风险评估?
- 2024-12-23优化库存,提升效率:医药企业如何借助看板软件实现仓库智能化
- 2024-12-23项目管理零负担!轻量化看板工具如何助力团队协作
- 2024-12-23电商活动复盘,为何是团队成长的核心环节?
- 2024-12-23鸿蒙Next ArkTS高性能编程实战
- 2024-12-23数据驱动:电商复盘从基础到进阶!
- 2024-12-23从数据到客户:跨境电商如何通过销售跟踪工具提升营销精准度?