Servlet
一、Servlet规范
1、Servlet规范来自JavaEE规范中的一种
2、作用:
1)指定动态资源文件开发步骤
2)指定HTTP服务器调用动态资源文件规则
3)指定HTTP服务器管理动态资源文件实例对象规则
二、Servlet接口实现类
1、Servlet接口来自Servlet规范下的一个接口,这个接口存在于HTTP服务器提供的jar包中
2、Tomcat服务器下lib文件中有一个servlet-api.jar存放servlet接口(javax.servlet.Servlet接口)
3、Servlet规范中任务,HTTP服务器能调用的动态资源文件必须是一个Servlet接口实现类
三、Servlet接口实现类开发步骤
1、创建一个Java类继承HttpServlet超类,使之称为一个Servlet接口实现类
抽象类的作用:
降低接口实现类对接口实现过程的难度
将接口中不需要使用的抽象方法交给抽象类进行完成
Servlet接口
init方法
getServletConfig方法
getServletInfo方法
destory方法
这四个方法对Servlet接口实现类没用
public class oneServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
//tomcat Servlet oneServlet = new OneServlet();
//tomcat oneServlet.service()处理需求
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
Tomcat根据Servlet规范调用Servlet接口实现类规则:
1)Tomcat有权创建Servlet接口实现类实例对象:
Servlet oneServlet = new OneServlet();
2)Tomcat根据实例对象调用service方法处理当前请求
oneServlet.service()
2、重写HttpServlet父类的两个方法。doGet()或者doPost()
3、将Servlet接口实现类信息注册Tomcat服务器
在当前网站下面找到web文件夹,->WEB-INF文件夹->web.xml文件
<!--将Servlet接口实现类类路径地址交给Tomcat-->
<servlet>
<servlet-name>mm</servlet-name><!--声明一个变量存储servlet接口实现类类路径-->
<servlet-class>com.bjpowernode.controller.OneServlet</servlet-class><!--声明servlet接口实现类类路径-->
</servlet>
//此时Tomcat读取此信息之后会在内存中声明一个变量
Tomcat mm = "com.bjpowernode.controller.OneServlet";
http://localhost:8080/myWeb/com/bjpowernode/controller/OneServlet.class
<!--为了降低用户访问Servlet接口实现类难度,需要设置简短请求别名-->
<servlet-mapping>
<servlet-name>mm</servlet-name>
<url-pattern>/one</url-pattern><!--设置简短请求别名,别名在书写时必须以'/'为开头-->
</servlet-mapping>
http://localhost:8080/myWeb/one
四、Servlet对象生命周期
1、网站中所有的Servlet接口实现类的实例对象只能由http服务器负责创建,开发人员不能手动创建Servlet接口实现类的实例对象
2、在默认情况下,http服务器接收到对于当前Servlet接口实现类第一次请求时,自动创建这个Servlet接口实现类的实例对象
在手动配置时可以要求http服务器在启动的时候自动创建某个Servlet接口实现类的实例对象
<servlet>
<servlet-name>mm</servlet-name><!--声明一个变量存储servlet接口实现类类路径-->
<servlet-class>com.bjpowernode.controller.OneServlet</servlet-class><!--声明servlet接口实现类类路径-->
<load-on-startup>30</load-on-startup><!--填写一个大于0的整数,默认值是0。在启动的时候new实例对象-->
</servlet>
3、在http服务器运行期间,一个Servlet接口实现类只能创建一个实例对象。(一个进程对应多个线程)
4、在http服务器关闭时会将网站中所有的Servlet实例对象进行销毁。
五、HttpServletResponse接口
1、介绍
1)HttpServletResponse接口来自Servlet规范中,在Tomcat中存在于servlet-api.jar
2)此接口实现类由Http服务器提供
3)此接口负责将doGet/doPost方法执行结果写入响应体中交给浏览器
4)开发人员习惯于将HttpServletResponse接口修饰的对象成为响应对象
2、主要功能
1)将执行结果以二进制形式写入到响应体中
2)设置响应头中**[content-type]属性值,从而控制浏览器使用编译器将响应体二进制数据编译为文字、图片、视频、命令**
3)设置响应头中**[location]**属性,讲一个请求地址赋值给location,从而控制浏览器向指定服务器发送请求
@WebServlet(name = "oneServlet")
public class oneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result = "Helloworld";
//***********通过响应对象将结果写入响应体**********
//1.通过响应对象向Tomcat索要输出流
PrintWriter out = response.getWriter();
//2.通过输出流,将执行结果以二进制形式写入响应体
out.write(result);
}//doGet()执行完毕
//Tomcat将响应包推送给浏览器
}
@WebServlet(name = "twoServlet")
public class twoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int money = 100;
PrintWriter out = response.getWriter();
//write方法可以将字符、字符串、ASCII码写入响应体中
//收到一个数字的时候会当做ASCII码写入
//out.write(money);
//print方法
out.print(money);
}
}
@WebServlet(name = "threeServlet")
public class threeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//换行<br/>
String result = "Java<br/>MySQL<br/>HTML<br/>";
//设置响应头content-type
response.setContentType("text/html;charset=utf-8");
//向Tomcat索要输出流
PrintWriter out = response.getWriter();
//通过输出流将结果写入响应体
out.print(result);
String result2 = "真好<br/>!";
out.print(result2);
/*
* 浏览器在收到响应结果时,将<br/>作为文字内容在窗口中展示,并没有将其作为命令
* 问题原因:
* 浏览器在收到响应包之后根据响应头中的content-type属性的值,赖彩永对应编译器对相应体中的二进制内容进行编译
*
* 在默认情况下,content-type的值"text" content-type="text"
* 此时浏览器将会采用 文本编辑器 对响应体中的二进制数据进行解析
*
* 解决方案:
* 一定要在得到输出流之前,通过响应对象对响应头重的content-type属性进行一次重新赋值,用于指定浏览器采用正确的编译器
* */
}
}
@WebServlet(name = "fourServlet")
public class fourServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//浏览器的请求行为
String result = "http://www.baidu.com?userName=zzz";
//通过响应对象,将地址赋值给响应头中的location属性
response.sendRedirect(result);//响应头中 location="http://www.baidu.com"
/*
* 浏览器在接收到响应包之后如果发现响应头中存在location属性,
* 就会自动通过地址栏向location指定网站发送请求
*
* sendRedirect()方法远程控制浏览器请求行为【请求地址,请求方式,请求参数】*/
}
}
<?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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>oneServlet</servlet-name>
<servlet-class>oneServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>threeServlet</servlet-name>
<servlet-class>com.zfq.threeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>threeServlet</servlet-name>
<url-pattern>/three</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>twoServlet</servlet-name>
<servlet-class>com.zfq.twoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>twoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>fourServlet</servlet-name>
<servlet-class>com.zfq.fourServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fourServlet</servlet-name>
<url-pattern>/four</url-pattern>
</servlet-mapping>
</web-app>
六、HttpServletRequests接口
1、介绍
1)此接口来自Servlet规范中,在Tomcat中存在于servlet-api.jar
2)此接口实现类由Http服务器提供
3)此接口负责在doGet/doPost方法运行时读取http请求协议包中的信息
4)开发人员习惯于将HttpServletRequest接口修饰的对象成为请求对象
2、主要功能
1)读取请求协议包中请求行中的信息
2)读取保存在http请求协议包中请求头或者请求体中的请求参数信息
3)可以代替浏览器向http服务器申请资源文件调用
@WebServlet(name = "oneServlet")
public class oneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象读取 请求行 中的 url 信息
String url = request.getRequestURL().toString();
//通过请求对象读取 请求行 中的 method 信息
String method = request.getMethod();
//通过请求对象读取 请求行 中的uri 信息
/*
* URI:资源文件精准定位地址,在请求行中并没有URI这个属性
* 实际上URL中截取的一段字符串
* 格式:"/网站名/资源文件名"
* 作用:用于让http服务器对被访问的资源文件进行定位
*/
String uri = request.getRequestURI();
System.out.println("url "+url);
System.out.println("method "+method);
System.out.println("uri "+uri);
}
}
public class twoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象获得 请求头 中 所有请求参数名
Enumeration parameter = request.getParameterNames();//将所有的请求参数名称保存到一个枚举对象进行返回
while(parameter.hasMoreElements()){
String paramName = (String)parameter.nextElement();
//通过请求对象读取指定的请求参数的值
String value = request.getParameter(paramName);
System.out.println("请求参数名 "+paramName+"请求参数值 "+value);
}
}
public class threeServlet extends HttpServlet {
/*
* 以get方式发送中文参数内容,得到正常结果
* 以post方式发送中文参数内容,得到乱码
*
*
*
* get方式发送请求,请求参数保存在请求头中
* post方式发送请求,请求参数保存在请求体中
*
* 在http协议包到达http服务端之后第一件事是解码:
* 请求头:由tomcat解码,tomcat9.0默认使用utf-8字符集
* 请求体:由当前请求对象request负责解码,request默认使用[ISO-8859-1]字符集(东欧语系字符集),如果使用中文就无法解码
*
*
*
* 解决方案:
* 在post请求方式下,在读取请求体的内容之前,应该通知请求对象使用utf-8字符集对请求体中的内容进行一次重新解码*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象读取 请求体 中的信息
request.setCharacterEncoding("utf-8");
String userName = request.getParameter("userName");
System.out.println(userName);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求对象读取 请求头 中的信息
String userName = request.getParameter("userName");
System.out.println(userName);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<form action="/myweb/three" method="get">
请求参数:<input type="text" name="userName"/><br/>
<input type="submit" value="get方式访问threeServlet">
</form>
<form action="/myweb/three" method="Post">
请求参数:<input type="text" name="userName"/><br/>
<input type="submit" value="post方式访问threeServlet">
</form>
</center>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<a href="/myweb/two?userName=mm&password=123">通过超链接访问twoServlet并携带请求参数</a>
</center>
</body>
</html>
<?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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>oneServlet</servlet-name>
<servlet-class>com.zfq.oneServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>twoServlet</servlet-name>
<servlet-class>com.zfq.twoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>threeServlet</servlet-name>
<servlet-class>com.zfq.threeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>threeServlet</servlet-name>
<url-pattern>/three</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>twoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
</web-app>
七、请求对象和响应对象的生命周期
1、在http服务器收到浏览器发送的http请求协议包之后,自动为当前的http请求协议包生成一个请求对象和一个响应对象。
2、在http服务器调用doGet/doPost方法时,将 请求对象和响应对象作为实参传递到方法中。
3、在http服务器准备推送http响应协议包之前,将本次请求关联的请求对象和响应对象销毁。