1、servlet介绍
1.1、什么是servlet
- servlet是javaEE的规范之一,也就是接口
- servlet是javaweb的三大组件之一,分别是servlet程序,Filter过滤器,Listener监听器
- servlet是运行在服务器上的例如Tomcat上的一个java程序
1.2、手动实现servlet程序的步骤
1.2.1、编写一个类来实现servlet接口
1.2.2、实现service方法
1.2.3、在web.xml中配置servlet程序的访问地址
创建一个servlet类然后实现他的方法
package com.wyg.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-15 23:26
*/
public class HelloServlet 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 {
System.out.println("servlet程序被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
配置web.xml
<?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>HelloServlet</servlet-name>
<servlet-class>com.wyg.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
2、servlet的生命周期
- servlet调用构造器方法
- servlet调用init初始化方法
- servlet调用service方法(里面还会执行doGET和doPOST方法)
- servlet调用destroy销毁方法
package com.wyg.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-15 23:26
*/
public class HelloServlet implements Servlet {
public HelloServlet(){
System.out.println("1、构造器方法执行");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2、init方法执行");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3、servlet程序被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4、执行销毁方法");
}
}
可以看到,在整个程序执行时,servlet程序会依次执行构造器方法,init方法,service方法,最后程序停止时会执行销毁方法,避免资源被占用。
3、get请求与post请求的分发
servlet程序
package com.wyg.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-15 23:26
*/
public class HelloServlet implements Servlet {
public HelloServlet(){
System.out.println("1、构造器方法执行");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2、init方法执行");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3、servlet程序被访问了");
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if("GET".equals(method)){
doget();
}else if("POST".equals(method)){
dopost();
}
}
public void doget(){
System.out.println("桥本环奈执行了get方法");
}
public void dopost(){
System.out.println("桥本环奈执行了post方法");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4、执行销毁方法");
}
}
submit.html程序
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8088/javaweb/hello" method="post">
<button type="submit">桥本环奈</button>
</form>
</body>
</html>
3.1、get请求
<body>
<form action="http://localhost:8088/javaweb/hello" method="get">
<button type="submit">桥本环奈</button>
</form>
</body>
3.2、post请求
<body>
<form action="http://localhost:8088/javaweb/hello" method="post">
<button type="submit">桥本环奈</button>
</form>
</body>
3.3、通过继承HttpServlet类实现servlet类
package com.wyg.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-16 17:03
*/
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("桥本环奈执行了doget方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("桥本环奈执行了dopost方法");
}
}
web.xml
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.wyg.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
4、ServletConfig类
4.1、三大作用
- 获取Servlet程序的别名servlet-name的值
System.out.println("servlet程序的别名:"+servletConfig.getServletName());
- 获取初始化参数init-parm
System.out.println("servlet程序的参数init-parm:"+servletConfig.getInitParameter("用户名")); System.out.println("servlet程序的参数init-parm:"+servletConfig.getInitParameter("密码"));
- 获取servletContext对象
-
System.out.println("获取ServletContext对象:"+servletConfig.getServletContext());
5、ServletContext类
5.1、什么是ServletContext类
- ServletContext是一个接口,表示Servlet的上下文对象
- 一个web工程只有一个ServletContext对象
- ServletContext对象是一个域对象
域对象是一个可以想Map一样可以存取数据的对象
5.2、ServletContext类的四个作用
- 获取web.xml中配置的上下文参数context-param
<!--Context-param是上下文参数(属于整个web工程)-->
<context-param>
<param-name>姓名</param-name>
<param-value>迪迦</param-value>
</context-param>
<context-param>
<param-name>年龄</param-name>
<param-value>500</param-value>
</context-param>
System.out.println("工程路径"+context.getContextPath());
System.out.println("服务器硬盘上的绝对路径:"+context.getRealPath("/"));
ServletContext context = getServletContext();
context.setAttribute("姓名","赛罗");
System.out.println("context获取域数据中key的值"+context.getAttribute("姓名"));
6、HttpServletRequest类
6.1、HttpServletRequest类的作用
通过HttpServletRequest对象获取所有被Http协议信息封装的request对象的所有请求2信息。
6.2、HttpServletRequest类的常用方法
- getRequestURI 获取请求的资源路径
- getRequestURL 获取请求的绝对路径
- getRemoteHost() 获取请求的客户端ip
- getHeader() 获取请求头
- getParameter() 获取请求参数(一个值)
- getParameterValues() 获取请求参数(多个值)
- getMethod() 获取请求的方法
- setAttribute(); 设置域数据
- getAttribute(); 获取域数据
- getRequestDispatcher() 获取请求转发对象
6.3、doget与dopost的乱码问题
在doget中,我们解决乱码的顺序是先获取请求参数,要先以iso8859-1进行编码,再以utf-8进行解码
例如:
String password = req.getParameter("password");
password=new String(password.getBytes("iso8859-1"),"UTF-8")
在dopost中,我们可以直接设置设置请求体的字符集为UTF-8
req.setCharacterEncoding("UTF-8");
7、请求转发
7.1、什么是请求转发
什么是请求转发呢?那就不得不提到转发与重定向的区别
重定向:你先去了公安局,说你要寄东西,公安局的人说:“这个事情不归我们管,去邮局”,然后告诉了你去邮局的路,你就从公安局走了,自己乘车去了邮局。
转发:你先去了公安局,公安局看了以后,知道这个事情其实应该邮局来管,但是他没有让你走,秉持着为人民服务的精神理念,自己把东西送到邮局,帮你把事情办了。
ServletTest1
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher servletTest2 = request.getRequestDispatcher("/servletTest2");
servletTest2.forward(request,response);
}
ServletTest2
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("已转发到ServletTest2");
}
web.xml
<servlet>
<servlet-name>ServletTest1</servlet-name>
<servlet-class>com.wyg.servlet.ServletTest1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest1</servlet-name>
<url-pattern>/servletTest1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ServletTest2</servlet-name>
<servlet-class>com.wyg.servlet.ServletTest2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest2</servlet-name>
<url-pattern>/servletTest2</url-pattern>
</servlet-mapping>
8、HttpServletResponse类
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于请求的request对象、和响应的response对象。
我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。既然是请求和响应,那一定会有数据的产生,那就要说到两个输出流,一个是字节流一个是字符流。
- 字节流 getOutputStream() 用于文件下载
- 字符流 getWriter() 用于回传字符串
注意:在一个Servlet程序中,两个流只能使用一个,使用了字节流就不能使用字符流,使用了字符流就不能使用字节流。
//获取响应内容
PrintWriter writer = response.getWriter();
writer.write("迪迦把怪兽打屎了 ");
web.xml
<servlet>
<servlet-name>ServletResponse</servlet-name>
<servlet-class>com.wyg.servlet.ServletResponse</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletResponse</servlet-name>
<url-pattern>/servletResponse</url-pattern>
</servlet-mapping>
我们服务器的字符集为ISO-8859-1,而浏览器的默认字符集为GBK,所以引起了乱码。此时我们需要设置字符集
//设置服务器字符集为utf-8
response.setCharacterEncoding("UTF-8");
//设置浏览器的字符集为UTF-8
response.setHeader("Content-Type","text/html;charset-UTF-8");
9、请求重定向
ResponseTest1
package com.wyg.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-18 22:33
*/
public class ResponseTest1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("ResponseTest1 已废弃,马上跳转到ResponseTest2");
resp.sendRedirect("http://localhost:8088/javaweb/responseTest2");
}
}
ResponseTest2
package com.wyg.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author shkstart
* @create 2021-12-18 22:39
*/
public class ResponseTest2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(" 双眼失明丝毫不影响我追捕敌人,因为我能闻到他们身上的臭味");
}
}
web.xml
<servlet>
<servlet-name>ResponseTest1</servlet-name>
<servlet-class>com.wyg.servlet.ResponseTest1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResponseTest1</servlet-name>
<url-pattern>/responseTest1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ResponseTest2</servlet-name>
<servlet-class>com.wyg.servlet.ResponseTest2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResponseTest2</servlet-name>
<url-pattern>/responseTest2</url-pattern>
</servlet-mapping>