Servlet 基础
简述
什么是Servlet?
Servlet是用Java语言编写应用到Web服务器端的扩展技术,他先于JSP产生,可以方便地对Web应用中的HTTP请求进行处理。在JavaWeb程序开发中,Servlet主要用于处理各种业务逻辑,它比JSP更具有业务逻辑层的意义,而且Servlet在安全性,扩展性以及性能方面都十分优秀,它在JavaWeb程序开发以及MVC框架的应用方面起到了极其重要的作用。
结构体系
HttpServlet类继承GenericServlet类,GennericServlet类继承三个接口,分别是Servlet接口,ServletConfig接口,Serializable接口。其中Serializable接口是java.io包中的序列化接口;Sevlet接口和ServletConfig接口是java.servlet包中定义的对象,其中,Servlet接口定义了Servlet的基本方法,ServletConfig接口封装了相关配置信息;GennericServlet是一个抽象类,它只是对上面继承的三个接口部分实现,但没有实现POST,GET等方法,而这些实现都是通过其子类HttpServlet类实现。
优势
- 1.功能强大
Servlet采用Java编写,它可以调用Java的API。
- 2.可移植
Java语言是跨平台的,也与协议无关,而由Java编写的Servlet继承了Java的优点。
- 3.性能高效
Servlet对象在Servlet容器启动时初始化,但第一次被请求时,Servlet容器将被实例化,此时它储存于内存中。如果存在多个请求,Servlet不会再被实例化,仍然由此Servlet容器对其进行处理。每一个请求是一个线程,而不是一个进程,因此,Servlet容器对请求处理的性能是十分高效的。
- 4.安全性高
Servlet使用了Java的安全框架,同时Servlet容器还扩展了功能。
- 5.可扩展
Java语言是面向对象的编程语言,Servlet由Java语言编写,所以它继承了Java语言的面向对象的优点,在业务逻辑处理中,可以通过封装、继承等来扩展实际的业务需求。
Servlet方法执行过程:
package com.wu.ServletDemo;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet(name = "myservlet",urlPatterns = "/demo")
public class Myservlet implements Servlet{
@Override
public void destroy() {
System.out.println("最后执行,且每次关闭Tomcat都有且只会执行一次");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("最先执行,且每次启动Tomcat都有且只会执行一次");
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("每次客户端发送一次请求就执行一次");
}
}
结果:
servlet生命周期:
- 1.但浏览器访问Servlet的时候,Tomcat会先判断是否存在Servlet实例化对象,如果不存在,则通过反射机制实例化Servlet对象,否则进入直接执行service方法
- 2.调用init方法完成初始化操作
- 3.调用service方法完成业务操作
- 4.关闭Tomcat时,调用destroy方法,释放当前对象的资源
Servlet示例
1.通过XML配置文件方式访问Servlet
index.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MyServlet 实验</title>
<script src = "JQuery/jquery-3.2.1.js"></script>
<script type = "text/javascript">
var httpRequest; // 创建ajax请求对象
function createXMLHttpRequest(){
httpRequest = new XMLHttpRequest();
}
function sendRequest(){
createXMLHttpRequest();
try{
httpRequest.onreadystatechange = handleState; // 绑定函数
httpRequest.open("get","demo",true); // 初始请求参数
httpRequest.send(null); // 发送请求
}catch(e){
alert("您访问的资源不存在!");
}
}
function handleState(){
if(httpRequest.readyState == 4 && httpRequest.status == 200){
var data = httpRequest.responseText;
var divObj = document.getElementById("mydiv");
divObj.innerHTML = data;
console.log("服务器已收到消息");
}
}
$(function(){
var h = document.getElementById("h2");
h.onclick = function(){
sendRequest();
}
});
</script>
</head>
<body>
<div id = "mydiv" align = "center" style = "color:blue"><h2 id = "h2" >Hello Servlet !</h2></div>
</body>
</html>
MyServlet:
package com.wu.ServletDemo;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class Myservlet implements Servlet{
@Override
public void destroy() {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("客户端访问servlet成功!");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<h2>Hello Browser !</h2>");
}
}
web.xml:
<?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_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>web2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>servletDemo</servlet-name>
<servlet-class>com.wu.ServletDemo.Myservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
2.通过注解方式访问Servlet
删除web.xml文件,在Myservlet中添加以下语句:
import javax.servlet.annotation.WebServlet;
@WebServlet(name = "myservlet",urlPatterns = "/demo")
也可以具有完全一样的效果,简化了操作,因此一般都是采用注解方式。
ServletConfig接口
public String getInitParameter(String name) // 获取String类型的初始化参数
public Enumeration getInitParameterNames() // 获取所有参数初始化枚举集合
public ServletContext getServletContext() // 用于获取Servlet上下文对象
public String getServletName() // 返回Servlet对象的实例名
HttpServletRequest接口
public String getContextPath() // 返回请求的上下文路径
public Cookie[] getCookies() // 返回请求中发送的所有Cookie对象,返回值为Cookie数组
public String getMethod() // 返回请求所使用的HTTP类型
public String getQueryString() // 返回请求中参数的字符串形式
public String getRequestURI() // 返回主机名到请求参数的字符串形式
public StringBuffer getRequestURL() // 返回请求URL,类型为StringBuffer
public String getServletPath() // 返回请求中URI中的Servlet路径字符串
public HttpSession getSession() // 返回与请求关联的HttpSession对象
HttpServletResponse接口
public void addCookie(Cookie cookie) // 向客户端写入Cookie信息
public void sendError(int sc) // 发送一个错误状态码为sc的错误响应到客户端
public void sendRedirect(String location) // 使用客户端重定向到新的URL,参数为新的地址
HttpServlet代码结构
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
// 初始化方法
public void init() throws ServletException{
}
// 处理HTTP GET请求
public void doGet(HttpServletRequest request , HttpServletResponse response) throws
ServletException , IOException{
}
// 处理HTTP POST请求
public void doPost(HttpServletRequest request , HttpServletResponse response) throws
ServletException , IOException{
}
// 处理HTTP PUT请求
public void doPut(HttpServletRequest request , HttpServletResponse response) throws
ServletException , IOException{
}
// 处理HTTP DELETE请求
public void doDelete(HttpServletRequest request , HttpServletResponse response) throws
ServletException , IOException{
}
// 销毁方式
public void destroy() {
super.destroy(); // 调用HttpServlet类的销毁方式
}
}
Servlet过滤器
package com.wu.FilterDemo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
public class MyFilter implements Filter{
// 初始化处理
@Override
public void init(FilterConfig filterConfig) throws ServletException{
}
// 过滤器处理方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response); // 过滤处理
}
// 销毁方法
@Override
public void destroy() {
}
}
基于注解方式的多个过滤器执行过程:
MyFilterA:
package com.wu.FilterDemo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName = "myfilterA" , urlPatterns = "/demo")
public class MyFilterA implements Filter{
// 初始化处理
@Override
public void init(FilterConfig filterConfig) throws ServletException{
}
// 过滤器处理方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("每次客户端发送一次请求FilterA就执行一次");
chain.doFilter(request, response); // 过滤处理
System.out.println("每次服务器发送一次响应FilterA就执行一次");
}
// 销毁方法
@Override
public void destroy() {
}
}
MyFilterB:
package com.wu.FilterDemo;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName = "myfilterB" , urlPatterns = "/demo")
public class MyFilterB implements Filter {
// 初始化处理
@Override
public void init(FilterConfig filterConfig) throws ServletException{
}
// 过滤器处理方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("每次客户端发送一次请求FilterB就执行一次");
chain.doFilter(request, response); // 过滤处理
System.out.println("每次服务器发送一次响应FilterB就执行一次");
}
// 销毁方法
@Override
public void destroy() {
}
}
MyServlet:
package com.wu.ServletDemo;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet(name = "myservlet",urlPatterns = "/demo")
public class MyServlet implements Servlet{
@Override
public void destroy() {
System.out.println("最后执行,且每次关闭Tomcat都有且只会执行一次");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("最先执行,且每次启动Tomcat都有且只会执行一次");
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("每次客户端发送一次请求Servlet就执行一次");
}
}
index.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Filter Demo</title>
</head>
<body>
<form action = "demo" method = "get">
<div align = "center">
<table>
<tr>
<td>用户名:</td>
<td><input type = "text" name = "username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type = "password" name = "password"></td>
</tr>
<tr>
<td colspan = "2" align = "center"><input type = "submit" value= "提交"></td>
</tr>
</table>
</div>
</form>
</body>
</html>
结果: