Servlet作用是处理请求 接收请求 处理请求 完成响应
课时2 实现Servlet方式依赖
javax.servlet
javax.servlet-api
4.0.1
provided
实现方式
// 实现接口:
javax.servlet.Servlet
// 继承类:
javax.servlet.GenericServlet
// 继承类:
javax.servlet.HttpServlet
继承示例 AServlet.java
import javax.servlet.*;
import java.io.IOException;
public class AServlet 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 {
}
// 获取servlet信息
@Override
public String getServletInfo() {
return null;
}
// 销毁前调用
@Override
public void destroy() {
}
}
课时3 Servlet的生命周期
生命周期
init 实例化调用
service 每次处理请求都调用
destroy 销毁调用
特性 (1)单例,每个类只有一个对象 (2)线程不安全,效率最高
Servlet类由用户自定义,对象由服务器来创建,并有服务器调用对应的方法
浏览器访问Servlet 给Servlet配置一个路径 web.xml
demo
AServlet
demo
demo
目录结构
webapp
└── WEB-INF
├── classes
│ └── AServlet.class
└── web.xml
课时4 ServletConfig介绍
interface ServletConfig{
// 获取servlet-name中的内容
String getServletName()
// 获取Servlet上下文对象
ServletContext getServletContext()
// 获取指定初始化参数值
String getInitParameter(String name)
// 获取所有初始化参数值
Enumeration getInitParameterNames()
}
name
Tom
获取参数
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(servletConfig.getInitParameter("name"));
}
课时5 ServletRequest和Servletresponse对象
interface ServletRequest;
interface ServletResponse;
课时6 GenericServlet介绍
GenericServlet可以只覆写service方法,不用全写
基本原理
import javax.servlet.*;
import java.io.IOException;
public class AServlet implements Servlet {
private ServletConfig config = null;
@Override
public void init(ServletConfig servletConfig) {
this.config = servletConfig;
this.init();
}
// 实现此方法,初始化后可以调用
public void init() {
}
@Override
public ServletConfig getServletConfig() {
return this.config;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
使用示例
import javax.servlet.*;
import java.io.IOException;
public class AServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
servletResponse.getWriter().write("hello");
}
}
课时7 HttpServlet介绍
源码
package javax.servlet.http;
public abstract class HttpServlet extends GenericServlet {
// 重写
protected void doGet(HttpServletRequest req, HttpServletResponse resp);
// 重写
protected void doPost(HttpServletRequest req, HttpServletResponse resp);
protected void service(HttpServletRequest req, HttpServletResponse resp);
public void service(ServletRequest req, ServletResponse res){
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
this.service(request, response);
} else {
throw new ServletException("non-HTTP request or response");
}
}
}
使用示例: 接收GET请求
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello");
}
}
课时8 Servlet的细节
1、非线程安全 一个Servlet类只有一个实例对象,不是线程安全的,工作效率高
(1)不要在Servlet中创建成员,创建局部变量即可 (2)可以创建无状态成员 (3)可以创建有状态的成员,但是状态必须为只读
2、创建时启动 默认情况下,服务器会在第一次访问Servlet时创建实例对象
给load-on-startup设置一个非负整数 正数的值越小,启动该servlet的优先级越高
可以配置创建时启动
servletName
0
3、url-pattern 可以有多个访问路径 可以使用前缀或者后缀通配符*
servletName
/demo/*
*.do
/*
课时9 在conf下的web.xml文件内容介绍
${CATALINA_HOME}/conf/web.xml
default
/
30
xml
application/xml
课时10 Servlet与反射
Servlet通过反射,获取配置文件的类名,进行实例化和方法调用
课时11 ServletContext概述一个项目只有一个ServletContext对象 可以在多个Servlet中传递对象
Tomcat启动时创建,关闭时销毁
课时12 获取ServletContext对象获取ServletContext
class ServeletConfig{
ServletContext getServletContext();
}
class GenericServlet{
ServletContext getServletContext();
}
课时13 演示ServletContext
域对象: 在多个Servlet中传递数据
class ServletContext{
// 设置 多次调用会覆盖
void setAttribute(String name, Object vlaue);
// 获取
Object getAttribute(String name);
// 移除
void removeAttribute(String name);
// 获取全部属性名称
Enumeration getAttributeNames();
}
例如: AServlet的数据可以传递到BServlet AServlet.java
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String name = request.getParameter("name");
ServletContext context = getServletContext();
context.setAttribute("name", name);
response.getWriter().write("" + name +"");
}
}
BServlet.java
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
String name = (String)context.getAttribute("name");
response.getWriter().println(name);
}
}
课时14 ServletContext获取公共的初始化参数
Servlet只能获取自己的初始化参数 ServletContext获取公共的初始化参数
key
value
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
String name = context.getInitParameter("key");
response.getWriter().println(name);
}
}
课时15 ServletContext获取资源相关方法
以webapp文根目录
ServletContext context = getServletContext();
// 获取绝对路径
String path = context.getRealPath("/index.html");
// 获取文件后转为输入流
InputStream in = context.getResourceAsStream("/index.html");
// 获取目录下的文件
Set set = context.getResourcePaths("/");
// [/hello.html, /WEB-INF/]
课时16 网站访问量统计小案例
使用ServletContext对象共享统计数据
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
Integer count = (Integer) context.getAttribute("count");
if (count == null) {
count = 1; // 第一次访问
} else {
count++;
}
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println("第"+count+"次访问");
context.setAttribute("count", count);
}
}
课时17 获取类路径下的资源
依赖
commons-io
commons-io
2.6
代码实例
package com.pengshiyu;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public class Demo {
public static void main(String[] args) throws IOException {
Class clazz = Demo.class;
// 1、相对于.class所在目录
InputStream input1 = clazz.getResourceAsStream("1.txt");
System.out.println(IOUtils.toString(input1, StandardCharsets.UTF_8));
// 2、相对于/classes
InputStream input2 = clazz.getResourceAsStream("/2.txt");
System.out.println(IOUtils.toString(input2, StandardCharsets.UTF_8));
ClassLoader loader = clazz.getClassLoader();
// 3、相对于/classes
InputStream input3 = loader.getResourceAsStream("3.txt");
System.out.println(IOUtils.toString(input3, StandardCharsets.UTF_8));
}
}
课时18 BaseServlet
一个Servlet中可以有多个请求处理方法
BaseServlet.java
package com.pengshiyu;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String methodName = req.getParameter("method");
if(methodName == null || methodName.trim().isEmpty()){
throw new RuntimeException("method is null or empty");
}
System.out.println(methodName);
// 通过参数获取方法
Class clazz = this.getClass();
Method method = null;
try {
method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("方法获取失败");
}
// 调用方法
try {
method.invoke(this, req, resp);
} catch (Exception e) {
throw new RuntimeException("调用失败");
}
}
}
AServlet.java
package com.pengshiyu;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends BaseServlet {
public void getAge(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("getAge");
}
public void getName(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("getName");
}
}
调用时传入查询参数 http://localhost:8080/demo/hello?method=getAge