路♂️一、背概念(作用)!
1.代表了一个服务器端,主要作用是用来和浏览器动态的交互
2.接收浏览器发来的请求+服务器给浏览器做出响应 核心功能!!!!
路♂️二、准备工作
1.在IDEA里创建一个web工程:
File- New - Project - 选择 Java Enterprise 并在右侧勾选Web Application(web.xml)--输出工程名称后Finish
2.整理web工程目录结构
在WEB-INF里,创建两个文件夹classes 和 lib
3.修改资源输出位置
File--Project Structrue--Modules -- Paths
选中Use module complile output path
将Output path 和 Test output path 全部选择为创建好的WEB-INF-classes路径
4.修改jar包存放位置
选中Paths 旁边的Dependencies 然后点击+号 找到WED-INF-lib目录选中后在弹窗中选择Jar Directory
5.用Idea整合Tomcat
打开idea,选中工具栏
然后点击Edit Configurations
然后点击+号找到Tomcat Server 选择Local
在Name除随便起个名字
在Application server: 处点击后面的Configure(查找目录)
在目录中找到Tomcat解压后的文件夹选中,点击ok即可
路♂️三、入门案例:创建Servlet程序
选中src-右键-New-Create New Servlet-输入Servlet类的名字和包名-
路♂️1.使用注解的方式
package cn.tedu.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/ServletDemo1") //()里的部分是制定的浏览器访问规则
public class ServletDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//打印一句话
System.out.println("欢迎来到Servlet的世界~");
//给浏览器做出响应
response.getWriter().write("hello servlet!!");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
2.不使用注解
在Servlet3.0后被注解代替,在3.0前需要自己配置:
ServletDemo1 cn.tedu.servlet.ServletDemo1 ServletDemo1 /o
3.测试
1,直接浏览器测试
http://localhost:8080/cgb2109javaweb2_war_exploded/ServletDemo1
本地服务器:localhost,Tomcat端口号:8080,项目名称:cgb2109javaweb2,idea默认的项目名称后缀_war_exploded
自己制定的访问方式:ServletDemo1
路♂️2.创建HTML网页测试
前后端连接起来 点我测试
路♂️四、Servlet的继承结构
HttpServlet extends GenericServlet implements Servlet
自定义一个Servlet有三种方式:可以实现一个Servlet接口,或者继承抽象类GenericServlet,或者继承HttpServlet
1.如果直接实现接口Servlet
Servlet接口是Servlet的编程规范,里面有很多抽象方法比如:init(),service(),destroy()
必须要重写所有抽象方法
2.如果继承GenericServlet
虽然GenericServlet 实现了Servlet接口,重写了抽象方法(空实现),但service()没有重写,如果要使用必须自己重写service()方法
路♂️3.选择继承HttpServlet
首先HttpServlet 帮我们重写了service()方法,并且进行了判断
如果你是get请求,就自动调用doGet()
如果你是post请求,就自动调用doPost()
而且可以使用更多的功能,使用起来不会强制重写某些方法
所以我们自定义Servlet选择第三种方法继承HttpServlet
路♂️五、Servlet的生命周期
分为三大阶段:
初始化阶段:由Servlet自动调用init();
提供服务:由Servlet自动调用service();
销毁:由Servlet自动调用destroy();
可以通过自定义一个Servlet程序后,重写init(),service(),destroy()的方式来测试
测试后发现
init() 方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是也可以指定 Servlet 在服务器第一次启动时被加载。 当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
servlet()方法
它是Servlet的核心,每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,并传递给这个方法一个请求(ServletRequest)对象和一个响应(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。 service() 方法会检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost等方法,我们只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。 doGet() 和 doPost() 方法是每次服务请求中最常用的方法。
destroy()方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、并执行其他类似的清理活动。在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。
路♂️Request请求
1.概述
Request对象用来解析请求参数,当浏览器访问服务器时,携带着一些请求参数,可以通过Servlet提供的Request对象提供的API来解析请求参数
2.常用的方法
getParameter("参数名")--根据参数名获取参数的值
getParameterValues()--获取到所有参数的值并存入数组
setCharacterEncoding()--设置请求的字符编码方式
getCharacterEncoding()--返回字符编码方式
setAttribute(String,Object) 存储此请求中的属性
getAttribute(String name) 返回指定属性的属性值
3.测试表单提交数据
创建HTML网页
自定义Servlet程序
package cn.tedu.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet( "/ServletDemo6")
public class ServletDemo6 extends HttpServlet {
//doPost方法如果请求中包含中文,一定中文乱码!
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf8");
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
System.out.println("doPost的"+user);
System.out.println("doPost的"+pwd);
}
//Tomcat 7.0以上doGet方法 如果请求为中文 不设置字符集 也不会乱码 底层处理过了
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
System.out.println("doGet的"+user);
System.out.println("doGet的"+pwd);
}
}
4.模拟Servlet解析请求参数的方式
package cn.tedu;
//模拟Servlet解析请求参数的对象Request
public class MyRequest {
public static void main(String[] args) {
//this是代表的本类对象,static里不能出现this,原因就是加载顺序
// this.getParamter();
MyRequest my = new MyRequest();
my.getParamter();
}
//1,getParamter()获取每个请求参数
public void getParamter(){
String url="http://localhost:8090/cgb2109javaweb03_war_exploded/ServletDemo6" +
"?user=jack&pwd=123" ;
// 1,按照?切割字符串,切出来两部分,存入数组
//[http://localhost:8090/cgb2109javaweb03/ServletDemo6,user=jack&pwd=123]
String[] strs = url.split("\?");//转义
// 2,重点解析数组中的第二个元素,下标为1的元素
String datas = strs[1];//user=jack&pwd=123
// 3,把第二步的结果,按照&切割
//[user=jack,pwd=123]
String[] data = datas.split("&");
// 4,遍历数组,获取每个数据
for(String s : data){//遍历两次,第一次s是user=jack,第二次s是pwd=123
// 5,按照=切割,得到数组 [user,jack],只要第二个元素
// String params = s.split("=")[1];//和下面两行等效,只是简写形式
String[] ss = s.split("=");
String params = ss[1];
System.out.println(params);
}
}
}
总结1:
Servlet什么时候会调用doPost()方法?什么时候会调用doGet()?
Servlet会调用getMethod()来获取用户的访问方式,如果是post会调用doPost;
Servlet 会调用getMethod()来获取用户的访问方式,如果是get 会调用doGet;
总结2:中文乱码问题?
get方式提交数据没有乱码问题,Tomcat已经配置好了(URIEncoding="utf-8"),不必关心
post方式提交的数据如果有中文一定乱码,request.setCharacterEncoding("utf-8");
路♂️5.前后端连通的综合案例:
需求: 综合案例: 1,准备前端HTML网页,让用户输入部门数据(编号,名称,地址) 2,准备DeptServlet,接受请求,并且解析请求参数 3,把解析成功的请求参数,进行入库 3.1,准备jar包 3.2,准备dept表(deptno,dname,loc) 3.3,准备JDBC代码,进行insert的SQL语句操作
1.准备HTML网页
前后端融合案例 [type="text"]{ width: 200px; height: 30px; background-color: pink; border-color: pink; border-radius: 10px; } [type="submit"]{ background-color:pink ; border-color:pink ; width: 80px; height: 40px; color: white; font-size: 15px; }
2.准备jdbc jar包
将jar包复制进web-WEB-INF -lib 中
然后在idea中点击File-Project Structure -Libraries 点击加号,找到刚复制到lib中的jar包后点击ok
3.准备好数据库
准备dept表(deptno,dname,loc)
3.准备Servlet和JDBC
package cn.tedu.servlet;
import com.sun.javaws.IconUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
@WebServlet( "/DeptServlet") //定义访问方式
public class DeptServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //HTML网页是form表单post方式提交数据
request.setCharacterEncoding("utf8");//设置post字符集防止中文乱码
String deptno = request.getParameter("deptno");//解析HTML input中name="deptno"的值
String dname = request.getParameter("dname");
String loc = request.getParameter("loc");
System.out.println(deptno+dname+loc);// 看看是否提交成功了
try {
Class.forName("com.mysql.jdbc.Driver"); //注册驱动
String url = "jdbc:mysql://localhost:3306/cgb2022?characterEncoding=utf8";
Connection c = DriverManager.getConnection(url, "root", "root");//获取数据库连接器
String sql = "insert into dept values (?,?,?)"; //骨架 ?是占位符
PreparedStatement s = c.prepareStatement(sql); //防止SQL攻击 使用高效的prepareStament
s.setObject(1,deptno); //设置第一个问号的值为,解析后的变量deptno
s.setObject(2,dname);
s.setObject(3,loc);
s.executeUpdate();//执行
s.close(); // 关流
c.close();
} catch (Exception e) {
e.printStackTrace(); // 打印出错误信息
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
6.请求转发
请求转发是服务器内部资源的一种跳转方式,即当浏览器发送请求访问服务器中的某一个资源时,该资源将请求转交给另外一个资源进行处理的过程,就叫做请求转发,具有以下特点: 1,请求转发整个过程是一次请求、一次响应 2,请求转发前后,浏览器地址栏地址不会发生变化(浏览器–访问–>A–转发–>B,地址栏地址始终指向A的地址) 3,请求转发前后的request对象是同一个 4,转发前后的两个资源必须属于同一个Web应用,否则将无法进行转发 5,使用代码: request.getRequestDispatcher(访问目的资源的路径).forward(request,response); 6,也可以使用 setAttribute()/getAttribute()来验证
测试:
先创建一个AServlet类 和一个BServlet类
package cn.tedu.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/AServlet") //定义AServlet的访问方法
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("AServlet被执行");
request.setAttribute("name","jack"); //存一KV值
request.getRequestDispatcher("/BServlet").forward(request,response); //请求转发到BServlet执行
}
}
package cn.tedu.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/BServlet") //设定访问方式方便A转发到B
public class BServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("BServlet被执行!");
Object value = request.getAttribute("name"); //根据AServlet里存的K值获取V值
System.out.println(value);//打印V值 能成功打印就可以证明请求转发前后使用的是同一个对象
}
}
路♂️response响应
是指从 java程序 组织好的 数据 发送给前端浏览器的过程,叫响应 (后端到前端的过程)
//常用方法:
getWriter();//--给浏览器响应数据(获取字符输出流)
setContentType("text/html;charset=utf-8"); //固定写法 解决响应到浏览器后中文乱码问题
重定向
1.整个过程有 两个 请求 两个响应
2.地址栏会发生改变 使用:response.sendRedirect(对方的访问方式),此时想访问哪个程序都可以
3.使用两个对象
路♂️面试题:重定向和请求转发的区别?
1.请求转发是request的功能,全程1次请求,1次响应,地址栏不变,对象只使用1个 只能转发同个web项目
request.getRequestDispather().forward(请求,响应);
2.重定向是response的功能,全程2次请求,2次响应,地址栏变更,对象使用两个 可以访问任何网址
response.sendRedirect("目标访问的方式");



