什么是Servlet
- Servlet是SUN定义的一组接口,规范而SUN自己并没有去实现它
- Tomcat是一个JavaWeb服务器也是一个Servlet容器
- Servlet的创建、运行、销毁都有Servlet容器完成
servlet 功能
1.浏览器是客户端,服务器是服务端,浏览器要浏览页面的话需要发送请求到服务器,服务器响应后,浏览器方可浏览,浏览器地址里一般使用绝对路径,服务器一般使用相对路径
2.网页(web page),是网站中的一「页」,通常是HTML格式(文件扩展名为。html或。htm或。asp或。aspx或。php或。jsp等)。网页通常用图像档来提供图画。网页要使用网页浏览器来阅读。
浏览器:万维网(Web)服务的客户端浏览程序。可向万维网(Web)服务器发送各种请求,并对从服务器发来的超文本信息和各种多媒体数据格式进行解释、显示和播放。
服务器指一个管理资源并为用户提供服务的计算机软件,通常分为文件服务器、数据库服务器和应用程序服务器。运行以上软件的计算机或计算机系统也被称为服务器。
三者关系:网页是网站中的一页,整个网站的资源都是放在服务器上的。我们浏览某一网页时,是要通过浏览器,发送请求,然后服务器根据发送的请求,传回相应的这一网页的数据给浏览器,浏览器然后解释并显示和播放传回的数据,即我们平时能看到的资料。
接收请求参数 业务处理(查询数据) 页面跳转(把数据响应给浏览器)
第一个Servlet程序
- 创建一个Web项目 2.导入Servlet的jar包 3自定义Servlet类 4. 在web.xml中配置Servlet
- 启动访问
http://ip地址:端口/上下文路径/我们自己的路径
Servlet的生命周期
javax.servlet.Servlet接口中的方法:
--------------------------------------------------------------------
public void init(ServletConfig config): 初始化方法
public void service(ServletRequest req, ServletResponse res):服务方法
public void destroy():销毁方法
public ServletConfig getServletConfig():返回当前Servlet的配置信息对象.
public String getServletInfo():该方法返回Servlet的信息(作者,版权等).
测试流程和步骤:
执行流程: 构造器-->init方法--> 循环[ service方法 ]--->destory方法(正常关闭Tomcat)
1:构造器先执行,创建Servlet对象:init,service,destory方法,都是非static方法,都得使用对象调用.
2:一个Servlet类在整个生命周期中最多只有一个对象.
3:init在构造器执行之后,立马执行,只执行一次,为对象做初始化操作.
4:service方法在每次请求都会执行.
5:destroy方法只有在正常关闭Tomcat时,才会执行,不要期望该方法一定执行,不要在该方法编写扫尾操作.
6:Servlet类必须使用public修饰,Servlet的构造器,必须是公共无参数的.原因在下一个知识点.
Servlet的执行流程
- 从浏览器输入地址(发起请求)开始分析: http://localhost:80/xx/hello
- localhost 也可能是ip 或者域名 ---》定位服务器主机
- 80 定位到tomcat
- xx 上下文路径,tomcat/conf/server.xml 中的
<Context docBase=”F:workspaceday11-servletwebapp” path=”xx” /> 中的path
通过上面的步骤找到了 docBase后面的项目的真实路径
根据约定去找到项目中的配置文件 web.xml
- web.xml内容分析:
- 找到url-pattern的值为 /hello
- 通过上一步中对应servlet-name 找到对应的servlet标签
- 找到对应的Servlet的完全限定名 cn.itsource._01hello.HelloServlet
仅仅是一个字符串而已,交给Tomcat进行处理
通过反射来创建对象并调用方法
- Tomcat对Servlet的创建:
- 通过上获得 servlet的完全限定名为参数使用反射来创建一个对象
Class clz = Class.forName(“cn.itsource._01hello.HelloServlet”)
Clz.newInstance() 要求自己的Servlet类必须有公共的无参数的构造方法
- 如果是第一次访问,就会创建一个Servlet的对象,并缓存起来
- 2
- 。。。N 直接先从缓存中看有没有,有直接使用调用service方法
filter 可以接受一些参数。 init-param 的param-name 就是参数名 param-value就是参数值, 支持多个参数
每一个 filter 都有一个 init 方法 ,可以再这个 方法中通过 getInitParamter("key"); key 就是 param-name的值,来获取对应的参数值
常用的 就是 设置编码过滤器 , 例如 : <init-param><param-name>encoding</param-name><parma-value>UTF-8</param-vaue></init-param>
init-param(初始化参数)
我们一般只执行service方法,但是现在我们直接实现Servlet接口,所有的方法都需要实现,每个实现类都这样做感觉...
使用适配器模式
写一个父类MyGenericServlet,这个父类去实现Servlet接口
之后我们的所有子类直接继承这个父类,只需要去完成service方法即可
请求和响应
HttpServlet
我们使用HttpServlet的三种方式:
1. 在GET里面调用POST 2. 在POST里面调用GET
3.(推荐)不管什么请求,直接在service中执行就可以了
HttpServlet继承了GenericServlet,而GenericServlet实现Servlet接口
HttpServletRequest
HttpServletRequest是ServletRequest接口的子接口,表示HTTP协议的请求对象.
既然HttpServletRequest是HTTP的请求对象,那么该接口中包含了获取各自请求信息的方法.
常用方法:
1. String getContextPath():获取上下文路径,<Context path="上下文" ../>
2. String getHeader(String headName):根据指定的请求头获取对应的请求头的值.
3. String getRequestURI():返回当期请求的资源名称. 上下文路径/资源名
4. StringBuffer getRequestURL():返回浏览器地址栏的内容
5. String getRemoteAddr():返回请求服务器的客户端的IP (remote;远程的)
通过注册示例说明:
(重要)获取请求参数的方法:
String getParameter(String name):根据参数名称,获取对应参数的值.
String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.
request.getParameterValues(String name)是获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkobx类型
request.getParameter(String name)是获得相应名的数据,如果有重复的名,则返回第一个的值 . 接收一般变量 ,如text类型
Enumeration<String> getParameterNames():获取所有请求参数的名字
Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.
key:参数名称
value:参数值,封装在String数组中.
ServletConfig中:
String getInitParameter(String name): 获取web.xml中配置初始化参数.
HttpServletRequest中:
String getParameter(String name): 获取用户在页面中填写的信息.
HttpServletResponse
HttpPServletResponse是ServletResponse的子接口,表示HTTP协议的响应对象.
该接口中包含了处理响应的方法.
OutputStream getOutputStream():获取字节输出流. :文件下载
Writer getWriter():获取字符输出流. :输出内容
上述两行代码,其实可以简写(合体):
设置输出的编码格式和内容类型:
和写如下:
请求中文乱码问题
1. 第一种解决乱码的问题:
request.setCharacterEncoding("UTF-8");
只支持POST,不支持GET
2.第二种
在server.xml中修改编码:URIEncoding="UTF-8"
只支持GET,不支持POST
3.第三种
String name = req.getParameter("name");
//将原来的码给转成二进制
byte[] nameBytes = name.getBytes("ISO-8859-1");
//再通过UTF-8的编码把这个数据转成相应的字符串
String nameStr = new String(nameBytes,"UTF-8");
GET与POST都支持
注:第二种与第三种在GET的情况下是冲突的,不能同时存在
ServletConfig(初始信息)
首先javaee文档中找到此接口
Servlet的继承体系(理解,今天放在最后一个点去复习)
我们从下面的一系列问题来摸索Servlet的继承体系:
我们一般只执行service方法,但是现在我们直接实现Servlet接口,所有的方法都需要实现,每个实现类都这样做感觉...
解决办法: 使用适配器模式
写一个父类MyGenericServlet,这个父类去实现Servlet接口
之后我们的所有子类直接继承这个父类,只需要去完成service方法即可
service(HttpServletRequest req, HttpServletResponse resp)
web.xml
<display-name>ss</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>hello.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/AA</url-pattern>
</servlet-mapping>
HelloServlet.java
package hello;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloServlet
*/
/*@WebServlet("/HelloServlet")*/
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登陆成功");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*System.out.println("你好吗");*/
}
}
index.html
<form action="AA" method="get">
用户名:<input type="text" name="username" placeholder="username"/><br>
密 码   :<input type="password" name="password" placeholder="password"/><br>
<input type="submit" value="注册"/><br>
<input type="checkbox" name="hobby"/><br>
</form>