Servlet
Servlet介绍
Servlet是一种服务器端的应用程序,可以动态生成Web页面,主要处理客户端发送的HTTP请求,并解析返回一个响应。
创建Servlet的方式
实现Servlet接口
| Servlet生命周期方法 | 含义 |
|---|---|
| Init() | 初始化的方法:Servlet生命周期初始化的方法,当Servlet容器创建这个Servlet的时候调用此方法,只执行一次 |
| Service() | 用户请求的方法,用户的每一次请求都会执行的这个方法,此方法会执行多次 |
| Destroy() | 销毁的方法,tomcat服务器停止的时候服务器会销毁Servlet,或者tomcat服务器卸载当前应用程序 |
实现步骤:
1.创建Servlet实现类 oneServlet implements Servlet
2.web.xml中进行配置和映射Servlet
注意每个方法都是由Servlet容器调用
层次关系Servlet的实现类是GenericServlet,GenericServlet的实现类是HttpServlet.
继承GenericServlet
GenericServlet实现了Servlet接口及ServletConfig接口
package com.hpe.javaweb;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 创建servlet的方式二:继承GenericServlet
*
*/
public class MyGenericServlet extends GenericServlet{
private static final long serialVersionUID = 5187828810473752635L;
@Override
public void init() throws ServletException {
System.out.println("init....");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service....");
// 获取Servlet名称
// 通过调用getServletConfig()可以得到ServletConfig对象
String name = getServletConfig().getServletName();
System.out.println(name);
// 得到web引用程序名称,/代表的是web应用程序的根路径
//ServletContext servletContext = getServletConfig().getServletContext();
ServletContext servletContext = getServletContext();
System.out.println(servletContext.getContextPath());
}
}
继承HttpServlet
package com.hpe.javaweb;
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;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet...");
String id = request.getParameter("id");
System.out.println(id);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求的编码格式
request.setCharacterEncoding("utf-8");
// 设置响应的编码格式
response.setContentType("text/html;charset=utf-8");
// 打印输出流
PrintWriter out = response.getWriter();
System.out.println("doPost...");
// 获取用户名和密码
String name = request.getParameter("username");
String password = request.getParameter("password");
//System.out.println("用户名:"+name+";密码:"+password);
out.print("<h1>登录成功</h1>");
}
}
Servlet生命周期(面试重点)
1.构造器:只有在第一次请求Servlet时,创建Servlet实例,调用构造器(Servlet是单实例的)
2.Init:创建好Servlet实例后,立即执行调用此方法.用于初始化当前的Servlet(只执行一次)
3.Service:用于响应请求的,每一次请求都会调用service方法(执行多次)
4.Destroy:当前的Servlet所在的Web应用被卸载时,或者tomcat服务器停止的时候,用于释放当前的servlet所占用的资源.(销毁)
Servlet生命周期
package com.hpe.javaweb;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 开发第一个Servlet
*/
public class OneServlet implements Servlet{
public OneServlet() {
System.out.println("1.构造器....");
}
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("2.初始化....");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("3.用户的请求....");
// 获得请求的参数
String name = req.getParameter("name");
// 设置响应的内容类型
res.setContentType("text/html;charset=utf-8");
// 响应输出到浏览器的内容
//res.getWriter().write("hello,"+name);
// 响应代码
res.getWriter().write("<span style='color:red'>"+name+"</span>");
}
@Override
public void destroy() {
System.out.println("销毁....");
}
// 用于获取当前Servlet的配置信息
@Override
public ServletConfig getServletConfig() {
return null;
}
// 获取servlet名称
@Override
public String getServletInfo() {
return null;
}
}
生命周期:
1.第一次启动,先调用构造器
2.再调用初始化方法
3.再执行用户的请求
4.再重复请求服务第二次第三次(还没关闭服务时)直接执行用户的请求
5.关闭服务、应用卸载时进行销毁
注意启动服务器运行这个Java文件,当然需要在XML中进行如下配置之后才能找到该Java文件路径。
配置Servlet
XML
1.可扩展标记语言
2.是用来描述数据或保存数据
3.使用文档类型(DTD)或者(XSD)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>servlet02</display-name>
<!-- 配置和映射Servlet -->
<servlet>
<!-- Servlet注册名称 -->
<servlet-name>oneServlet</servlet-name>
<!-- Servlet全类名 -->
<servlet-class>com.hpe.javaweb.OneServlet</servlet-class>
</servlet>
<!-- 配置如何访问servlet -->
<servlet-mapping>
<!-- 必须和某个声明的Servlet保持一致 -->
<servlet-name>oneServlet</servlet-name>
<!-- 访问的url路径,其中斜线代表当前web工程(的根目录localhost:8080/servlet02) -->
<url-pattern>/one</url-pattern>
</servlet-mapping>
<!-- 一个servlet可以有多个映射地址 -->
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/abc.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>
</web-app>
成功发布之后:
1.localhost:8080/servlet02/one可以访问上面的OneServlet
2.localhost:8080/servlet02/abc.html可以访问上面的OneServlet
3.localhost:8080/servlet02/1.action可以访问上面的OneServlet
4.localhost:8080/servlet02/action/a可以访问上面的OneServlet
ServletConfig接口
ServletConfig封装了Servlet的配置信息,并且可以获取到当前Web应用程序
Servlet常用的方法
| 常用的方法 | 作用 |
|---|---|
| getServletName() | 获取Servlet在web.xml中配置的名字 |
| getServletContext() | 获取代表当前web应用的ServletContext对象 |
| getInitParameter(String) | 获取当前Servlet指定名称的初始化参数的值 |
| getInitParameterNames() | 获取当前Servlet所有初始化参数的名字组成的枚举 |
注意
ServletConfig代表当前的Servlet是局部的
ServletContext代表整个web应用程序是全局的
@Override
public void init(ServletConfig servletConfig) throws ServletException {
String servletName = servletConfig.getServletName();
System.out.println("servlet名称:"+servletName);
String username = servletConfig.getInitParameter("username");
String password = servletConfig.getInitParameter("password");
System.out.println("username:"+username+";password:"+password);
Enumeration<String> names = servletConfig.getInitParameterNames();
while(names.hasMoreElements()){
// 参数名
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("name:"+name+";value:"+value);
}
ServletContext servletContext = servletConfig.getServletContext();
System.out.println(servletContext);
String company = servletContext.getInitParameter("company");
System.out.println("company:"+company);
Enumeration<String> names1 = servletContext.getInitParameterNames();
while(names1.hasMoreElements()){
// 参数名
String name = names1.nextElement();
String value = servletContext.getInitParameter(name);
System.out.println("name:"+name+";value:"+value);
}
// 获取当前web应用的某个文件的绝对路径
String realPath = servletContext.getRealPath("/hello");
System.out.println(realPath);
// 获取当前web应用程序的路径(非常重要)
String contextPath = servletContext.getContextPath();//打印的/servlet02
System.out.println(contextPath);
load-on-startup
- 值为负数的时候,调用相应Servlet才会创建相应实例
- 值为0或者正数的时候,值越小优先级越高,值相同的时候,由容器自行决定先创建哪一个
<servlet>
<servlet-name>oneServlet</servlet-name>
<servlet-class>com.hpe.javaweb.OneServlet</servlet-class>
<!-- 在Servlet容器启动时,加载Servlet(创建Servlet实例并且调用init方法) -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/abc.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oneServlet</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.hpe.javaweb.TwoServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
Servlet线程安全问题
- 尽量避免使用全局变量,可以使用局部变量
- 使用同步机制synchronized
public class ThreeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 成员变量
//private String name;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 接受用户请求的参数
String name = request.getParameter("name");
// 设置延时5秒
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(this + ",姓名:" + name);
}
}
序列号
private static final long serialVersionUID = 1L;
序列化:将内存中的对象的状态信息转化为可以存储或者传输的形式
本文详细介绍了Servlet的概念,创建方式,生命周期及其在Web开发中的作用。通过示例讲解了如何实现Servlet接口,继承GenericServlet和HttpServlet,以及配置和映射Servlet的过程。

被折叠的 条评论
为什么被折叠?



