Servlet 学习笔记
Servlet 运行在服务器上的 java 类;
Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据。
现在我们知道了 Servlet 是运行在服务器上的 Java 类,那么什么是服务器?我们平常最常用的服务器都有哪些呢?
服务器是一种被动程序:只有当Internet上运行其他计算机中的浏览器发出的请求时,服务器才会响应;
最常用的Web服务器是Apache和Microsoft的Internet信息服务器。
对于现在大多数 Javaweb 学习者大多数使用的是 Apache 服务器,所以我们今天也就从 Tomact 服务器开始。
Tomact 服务器的安装和配置
首先从官网上下载 Tomact 压缩包到本地,然后解压到你想要解压到的目录,会得到一个解压后的目录如下
--bin 存放启动和关闭 Tomact 的脚本文件
-- conf 存放 Tomact 服务器的各种配置文件
-- lib 存放第三方依赖 jar 包
-- logs 存放日志文件
-- temp 存放 Tomact 运行时产生的临时文件
-- webapp 发布 web 应用时,通常把 web 应用的目录和文件放到这个目录下
-- work 存放 jsp 被翻译为 Servlet 后编译的 class 文件
启动 Tomact 服务器
点击 bin/startup.bat 启动服务器;如果你点击之后只是闪了一下那么你可以查看日志文件查看错误信息,或者在 cmd 命令行下切换到 Tomact/bin 目录下,输入 startup 将会显示错误信息,而不是闪一下,找到错误信息之后发现它需要我们配置 JAVA_HOME(jdk 安装根目录) 或 JRE_HOME(jre 安装根目录) 中任何一个环境变量。
配置完成后再次点击便会成功启动服务器。
启动后在浏览器地址栏输入 localhost:8080(Apache 默认的端口号为 8080),如果出现 Apache 页面便说明启动成功(Tomcat 服务器只可以启动一个,如果你去启动第二个便会提示你端口被占用的错误信息)
我们如果每次启动服务器在命令行中的任意目录去启动而不需要在特定的目录该多方便?那么该如何实现呢?首先我们需要知道 PATH 环境变量,安装和配置 Java 时也会用到;
PATH是路径的意思,PATH环境变量中存放的值,就是一连串的路径。不同的路径之间,用英文的分号(;)分隔开。系统执行用户命令时,若用户未给出绝对路径,则首先在当前目录下寻找相应的可执行文件、批处理文件(另外一种可以执行的文件)等。若找不到,再依次在PATH保存的这些路径中寻找相应的可执行的程序文件。
如上面所述,我们把 bin 目录配置到系统环境变量 path 下,这样便不会出现错误信息(xxx 不是内部命令或外部命令,也不是可运行程序或批处理文件),但是会提示另一个错误,需要我们设置另外一个环境变量(CATALINA_HOME,Tomact 解压的根目录),同上我们去设置 CATALINA 环境变量。
设置成功后我们可以试着在任意目录下去输入 startup 来开启 Tomact。这时便可以正常启动服务器,你还可以在命令行中输入 catalina,查看 catalina 命令帮助,其中 catalina run 可以在当前窗口开启服务器,而不像 startup 那样开启另外一个窗口。开启之后可以按下 Ctrl + C 关闭服务器。
服务器介绍完毕,开始我们的正题 ---- Servlet。
1. 新建 web 工程,并新建一个类继承 Servlet 接口并实现其所有方法
2. 在 web 工程队的 web.xml 中映射 servlet 类,如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<!--Servlet 注册的名字-->
<servlet-name>helloServlet</servlet-name>
<!--Servlet 的全类名-->
<servlet-class>com.javaweb.firstServlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--同上一致-->
<servlet-name>helloServlet</servlet-name>
<!--映射访问的具体路径,/ 表示根目录-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
3. 我们继承 Servlet 接口的类如下,我们可以在 web 项目下的 jsp 文件中写一个超链接连接到 Servlet 的 URL,运行 web 项目执行 servlet,不断刷新页面,并在最后关闭服务器,我们可以看到控制台打印的消息,由此可知 servlet 执行顺序为(构造器-init 方法-service 方法 -----service 方法 – 关闭服务器调用 destroy 方法)
1. 构造器(只有第一次请求 Servlet 时创建 Servlet 实例调用构造器,说明 Servlet 是单实例,所以不可以写全局变量)
2. init(只被调用一次,在创建好实例后立即被调用,用于初始化当前 Servlet,构造器也可以初始化,但是 init 方法传入了构造器所没有的参数,所以使用 init 初始化 Servlet)
3. service(被调用多次,每次请求都会调用 Service 方法,被用于响应请求)
4. destroy(只被调用一次,在当前 Servlet 所在的 WEB 应用被卸载前调用,用于释放 Servlet 所占用的资源)
package com.javaweb.firstServlet; import javax.servlet.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration; public class HelloServlet implements Servlet{ @Override
public void init(ServletConfig servletConfig) throws ServletException { System.out.println("init");
} @Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
} @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service");
} @Override
public String getServletInfo() {
System.out.println("servletInfo");
return null;
} @Override
public void destroy() {
System.out.println("destroy");
} public HelloServlet() {
System.out.println("HelloServlet");
}
}
4. web.xml 文件 <servlet> 节点中可以指定load-on-startup 属性,指定 servlet 被创建的时机,其值越小越先被创建,若为负数则在第一次请求时被创建,若为 0 或正数则在容器被加载的时候被创建
现在我们开始详细的讲解 servlet 类及其对象
ServletConfig 类(封装了 Servlet 的配置信息,并且可以获取 ServletContext 对象)
方法: getInitParameter(String name) 获取指定参数名的初始化参数
getInitParametersNames() 获取初始化参数组成的 Enumeration 对象
首先我们需要会配置 servlet 初始化参数,如下
<servlet>
<!--Servlet 注册的名字-->
<servlet-name>helloServlet</servlet-name>
<!--Servlet 的全类名-->
<servlet-class>com.javaweb.firstServlet.HelloServlet</servlet-class>
<!--配置初始化参数,必须在 load-on-startup 节点前面-->
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>zy961029</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
ServletContext 对象(可以认为是当前 WEB 应用的大管家 )
定义了一组和 Servlet 容器通信的方法,每个应用程序都有一个 ServletContext(上下文),ServletContext 对象被称为application 对象,ServletContext 被包含在 ServletConfig 对象中,其拥有的方法和 servletConfig 一样,但获取的是当前 WEB 应用的初始化参数,当前 WEB 应用的初始化参数配置如下:
ServletContext 对象的方法众多可以参考其官方 API。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql:///sh_db</param-value>
</context-param>
<context-param>
<param-name>driverClass</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<web-app>
当前 WEB 应用的初始化参数和 Servlet 初始化参数的区别:
Servlet 初始化参数在当前 Servlet 中也就是 局部的,WEB 应用参数在 servlet 外边,相当于全局的,所有的 Servlet 可以获取
下面的是 ServletConfig 对象和 ServletContext 对象的方法实现
package com.javaweb.firstServlet; import javax.servlet.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration; /**
* Created by shkstart on 2017/11/06.
*/
public class HelloServlet implements Servlet{ @Override
public void init(ServletConfig servletConfig) throws ServletException {
// 获取当前 Servlet 的初始化参数
Enumeration<String> names = servletConfig.getInitParameterNames(); while (names.hasMoreElements()) {
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("name:" + name + "; value: " + value);
} // 获取当前 WEB 应用的初始化参数
ServletContext servletContext = servletConfig.getServletContext();
Enumeration<String> contextNames = servletContext.getInitParameterNames();
while (contextNames.hasMoreElements()) {
String contextName = contextNames.nextElement();
String contextValue = servletContext.getInitParameter(contextName);
System.out.println(contextName + "-->" + contextValue);
}
// 获取当前 WEB 应用的名称
String contextPath = servletContext.getContextPath();
System.out.println(contextPath + "+------+"); // 获取某一个文件对应的输入流
InputStream inputStream2 = servletContext.getResourceAsStream("/First.jsp");
System.out.println(inputStream2 + "-----+-----"); // 获取部署在服务器上的绝对路径
String realPath = servletContext.getRealPath("First.jsp");
System.out.println(realPath);
} @Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
} @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service");
} @Override
public String getServletInfo() {
System.out.println("servletInfo");
return null;
} @Override
public void destroy() {
System.out.println("destroy");
} public HelloServlet() {
System.out.println("HelloServlet");
}
}
ServletRequest 和 ServletResponse 对象
ServletRequest 封装了请求信息,可从中获取到任何的请求信息;ServletResponse 封装了响应信息,如果想给用户什么响应,具体可以使用该接口的方法实现 ,其常用方法有
String getParameter(String name); 获取请求的参数值,根据所传入的参数,例如输入框;
String[] getParameterValues() 返回参数的字符串类型的数组,例如多选框;
getWriter() 方法返回一个 PrintWirter 对象,打印到浏览器页面其他方法可以参考官方 PAI,在这里就不再啰嗦。
上面的方法具体如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="loginServlet">
UserName: <input type="text" name="userName"><br>
PassWord: <input type="password" name="passWord"><br>
Interest: <input type="checkbox" name="interest" value="TV">TV
<input type="checkbox" name="interest" value="MP3">MP3
<input type="checkbox" name="interest" value="SPORT">SPORT
<button type="submit">Submit</button>
</form>
</body>
</html>
package com.javaweb.firstServlet; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter; /**
* Created by shkstart on 2017/11/06.
*/
public class LoginServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException { } @Override
public ServletConfig getServletConfig() {
return null;
} @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
String userName = servletRequest.getParameter("userName");
String passWord = servletRequest.getParameter("passWord");
// 获取上面 jsp 文件中的输入框的值
System.out.println("userName: " + userName + "; passWord: " + passWord);
// 获取上面 jsp 文件中多选框的值
String[] interests = servletRequest.getParameterValues("interest");
for (String inter : interests) {
System.out.println("INTEREST: " + inter);
} // 获取请求的 URI,获取与 HTTP 请求有关的需要使用 ServletRequest 子接口 HttpServletRequst
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String uri = httpServletRequest.getRequestURI();
System.out.println(uri); String method = httpServletRequest.getMethod();
System.out.println(method); // 获取 Servlete 的映射路径
String servletPath = httpServletRequest.getServletPath();
System.out.println(servletPath); // 设置响应内容类型,为 word
// servletResponse.setContentType("application/msword"); PrintWriter printWriter = servletResponse.getWriter();
printWriter.print("HelloWorld");
} @Override
public String getServletInfo() {
return null;
} @Override
public void destroy() { }
}
如果每次都要像上面这样继承 Servlet 接口,且其大多数方法并不会经常用到,如果你感到这样很烦琐就对了,因为 Servlet 接口有一个子接口 GenericServlet,GenericServlet 实现了 Servlet 和 ServletConfig 接口的所有方法的一个抽象类,其中的 serevice 方法为抽象方法,因为每次请求都要去实现 service 方法;在其中 声明了一个 servletConfig 成员变量,在 init(ServletConfig) 方法中对其进行初始化;利用 ServletConfig 成员变量的方法实现了 ServletConfig 接口的方法,还定义了一个 init() 方法,在 init(ServletConfig) 方法对其进行调用,子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化,这样我们继承 GenericServlet 就可以极大简化我们的代码。
我们如果在 service 方法中想要获取有关 URL 的相关信息,我们还必须使用 HttpServletRequest 和 HttpServletResponse,如果我们继承 GenericServlet ,那么每次还需要去强制转换,特别麻烦,和上面所述一样我们有封装好的类去专门用作开发----HttpServlet,HttpServlet 继承自 GenericServlet,针对 HTTP 协议所定制;特点是在 service 方法中直接把 ServletRequest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse,并调用 service(HttpServletRequest resquest, HttpServletResponse response);
我们在平常开发中的 Servlet 便是继承自 HttpServlet,如果对上面所述的 GenericServlet 和 HttpServlet 想理解的更清楚可以去阅读源代码,看看他们的具体实现,下一篇文章将会对上面所述的四个对象的方法加以更加详细的讲解。
以上就是本周对 Servlet 学习的知识总结,有点乱,如果有什么疑问或者错误可以提出来我会尽快回复。
Servlet 学习笔记的更多相关文章
- # jsp及servlet学习笔记
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- Servlet学习笔记(三)
目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...
- Servlet学习笔记(二)
目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...
- jsp&servlet学习笔记
1.路径引用问题 一个css.jsp.html.或者javascript文件从从一个工程复制到另一工程,如果引用的时候使用的时相对路径,看似没有错误,但是却一直引用不进来,这时候要使用绝对路径,这样才 ...
- Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期
servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...
- Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain
笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤.最后response过滤,而且中间几项过滤的顺序不能动态改变.所 ...
- Servlet学习笔记(八)—— 文件下载
一.文件下载概述 比如图片或者HTML这类静态资源,仅仅要在浏览器中打开正确的网址就行下载.仅仅要资源放在应用程序文件夹或者其下的子文件夹中,但不在WEB-INF下.Servlet/JSP容器就会将资 ...
- JSP&Servlet学习笔记----第1/2章
HTML(HyperText Markup Language):超文本标记语言 HTTP(HyperText Transfer Protocol):超文本传输协议 URL(Uniform Resour ...
随机推荐
- VBA.NET 系统可行性分析模板
系统可行性分析 1. 技术可行性分析 前提: 系统不知在Window系统中,开发环境不受限制:系统以C/S结构为主,提供大量的数据操作:主要用VB.NET开发,提高安全性和访问效率. 基本要求 客户 ...
- FPGA在其他领域的应用(四)
工业领域: 从工厂和过程自动化到能源基础设施和机器视觉系统,工业产品有助于改善我们的世界.产品必须安全.可靠.适应性强,而且耐用.同时,商业成功要求你在激烈竞争的市场中行动迅速,同时降低总成本. 英特 ...
- C# XML序列化方法和常用特性
/* C#对象XML序列化(一):序列化方法和常用特性 .Net Framework提供了对应的System.Xml.Seriazliation.XmlSerializer负责把对象序列化到XML,和 ...
- 远程连接MySQL,防火墙阻止访问,解决方法
远程连接MySQL,防火墙阻止访问,解决方法 xp/2003添加防火墙例外端口 打开防火墙,选择例外选项卡,添加端口 名称:mysqlport 端口号:3306 选中TCP win7添加防火墙例外 ...
- Bootstrap文本排版基础--Bootsrap
1.排版前的基础 (1)移动设备优先 <meta name="viewport" content="width=device-width, initial-scal ...
- DevOps之存储和数据库
唠叨话 关于德语噢屁事的知识点,仅提供专业性的精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <数据(Data)> 了解有关数据部分.涉及存储及数据库的概念:知识与技能的层次( ...
- 在不用Promise的情况下如何控制异步请求?
如何更好的控制异步请求?相信大家一定首选Promise对象.确实,使用Promise控制异步请求确实非常方便,直接使用then()方法就可以实现当一个异步请求完成后再处理另一个请求或操作.同时,这样的 ...
- 【转载】quickLayout.css-快速构建结构兼容的web页面
文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/wordpress/ 原文链接:http://www.zhangxinxu.com/wordpress/?p=4 ...
- 【转载】基于vw等viewport视区相对单位的响应式排版和布局
文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/wordpress/ 原文链接:http://www.zhangxinxu.com/wordpress/?p=5 ...
- 【计算机网络基础】数据交换技术和多路复用技术的正(nao)确(can)打开方式
交换的作用 数据交换是计算机网络中两个终端进行数据传输的方式,它又可以分成两种类型:电路交换和分组交换.很显然,问题的核心在于“交换”,那么我们首先要思考的是:交换的作用是什么? “交换”的作 ...