Servlet详解
一、HTTP协议
HTTP概述
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,是一个基于请求与响应模式的、无状态的、应用层的协议,运行于TCP协议基础之上。
特点
基于客户端(浏览器)与服务器模式的协议(底层是TCP协议)
无连接:与UDP协议是由区别的,UDP是不会建立连接;HTTP的无连接是建立连接后,立马端口连接。
1.0版本:建立连接后立即端口
1.1版本:建立连接后,等待几秒再断开连接;如果此时还有其他访问请求,则可使用同一个访问资源
无状态:HTTP的访问是没有记忆能力的
通讯协议
客户与服务器建立连接(三次握手)。
客户向服务器发送请求。
服务器接受请求,并根据请求返回相应的文件作为应答。
客户与服务器关闭连接(四次挥手)。
请求报文
当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息(请求报文),HTTP请求信息由4部分组成:(查看f12的网络选项-点击访问链接) 1、请求行 请求方法/地址 URI协议/版本 2、请求头(Request Header) 3、空行 4、请求正文
响应报文
HTTP响应报文与HTTP请求报文相似,HTTP响应也由4个部分组成: 1、状态行 2、响应头(Response Header) 3、空行 4、响应正文
注意:要了解相关的响应状态码:200,302,404,500
二、Servlet详解
Servlet访问
前面Servlet的访问,需要创建MyServlet类去实现Servlet接口;然后在MyServlet类中需要重写5个方法;往往Servlet中只需要service方法,其余方法基本都是冗余,所以会有另外方便的Servlet访问方式。
继承GenericServlet
GenericServlet 是抽象类,实现了Servlet接口,且重写了Servlet的4个方法(除service方法外);我们继承了GenericServlet,则只需重写service方法。
继承HttpServlet(推荐)
HttpServlet是GenericServlet 的子类,里面重写了service方法,service方法中会调用doGet或doPost方法; 我们编写的MyServlet可继承HttpServlet,则不会直接提示重写
//继承GenericServlet方式
public class MyServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello,GenericServlet!!");
}
}
public class MyServlet2 extends HttpServlet {
/*
@Override //注意:此处的servcie和doget往往只用一个
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hello,HttpServlet!!!");
super.service(req,resp); //调用父类的service方法,才能触发到doGet
}*/
@Override //访问请求默认是get请求
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中可以配置映射路径,映射路径有多种方式: 精确匹配 /具体的名称 只有url路径是具体的名称的时候才会触发Servlet(推荐) 后缀匹配 * xxx 只要是以xxx结尾的就匹配触发Servlet 通配符匹配 / * 匹配所有请求,包含服务器的所有资源(过滤器常用) 通配符匹配 / 匹配所有请求,包含服务器的所有资源,不包括.jsp
自启动加载
在servlet标签中加入自启动标签,在启动tomcat时自动触发该servlet的init方法;自启动标签的基本值为正整数,值越小优先级越高。
<servlet>
<servlet-name>b</servlet-name>
<servlet-class>com.qf.a_servlet.MyServlet2</servlet-class>
<!--自启动标签(自启动对应servlet的init方法),基本值为正整数;值越小,优先级越高
-->
<load-on-startup>0</load-on-startup>
</servlet>
注解访问
注解访问,在项目中较常用;使用注解方式进行访问后,即可取代web.xml中的映射路径的配置
name: Serlvet名字 (可选)
value: 配置url路径,可以配置多个
urlPatterns:配置url路径 ,和value作用一样,不能同时使用
loadOnStartup: 如果是0或者正数 启动程序时自动触发init方法, 数值越小优先级越高。
@WebServlet("/my") //直接加映射路径
public class MyServlet extends GenericServlet {}
//urlPatterns与value类似 name: servlet-name value: url-pattern loadOnStartup:自启动
@WebServlet(name="a",value ="/my2",loadOnStartup=1)
public class MyServlet2 extends HttpServlet {}
三、Servlet应用
前端访问Servlet的方式有多种:url直接访问,超链接访问,表单访问
这三种方式,暂时只有表单方式可使用post请求
请求方式
get请求:
默认的访问方式就是get请求的方式,以url的方式传参数;优点:效率高 缺点:不安全
post请求:
现在只有表单方式可设置post请求,以请求体方式传参数; 优点:安全 缺点:效率低
post请求还可以在上传资源的场景中使用
<!--注意:action属性值;加了/则是绝对路径,从站点出发的路径(不携带上下文路径)
不加/则是相对路径,相对于当前上下文路径
-->
<form action="my2" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit" value="提交">
</form>
request
request请求对象,用于接收从客户端过来的参数
常用方法:
protected void service(HttpServletRequest request, HttpServletResponse response) {
request.setCharacterEncoding("utf-8"); //解决request的post乱码(get写和不写都没有乱码)
String name = request.getParameter("username"); //获取请求参数
String password = request.getParameter("password");
System.out.println(name+"--"+password);
System.out.println("请求方式:"+request.getMethod());// 获取请求方式
System.out.println("请求路径:"+request.getRequestURI()); //获取请求路径
request.setAttribute("name",name); //设置属性-存值;对应使用取值
System.out.println(request.getAttribute("name")); //根据key取值
}
response
response响应对象,用于将服务器的数据回传到客户端
常用方法:
//解决get/post的response方向乱码问题
response.setContentType("text/html;charset=utf-8");
//getWriter获取PrintWrite输出流 再调用write方法写出数据
response.getWriter().write("返回数据");
四、综合案例
要求:实现登录功能、展示所有用户功能
技术点:Servlet+JDBC+前端HTML展示
案例设计
1.表结构创建+实体类
2.DBUtils工具类设计
3.DAO层的接口与实现类(如果先写DAO层操作,可以先进行测试DAO层是否有问题)
4.Service层的接口与实现类
5.Servlet层处理浏览器的访问(用于取代测试类)
6.前端准备登录页面
表结构如下:
CREATE TABLE admin(
username VARCHAR(20) PRIMARY KEY,
password VARCHAR(20) NOT NULL,
phone varchar(11) NOT NULL,
address varchar(20) NOT NULL
)CHARSET=utf8;
INSERT INTO admin(username,PASSWORD,phone,address)
VALUES('zs','123','12345678901','北京市昌平区');
INSERT INTO admin(username,PASSWORD,phone,address)
VALUES('aaron','123456','12345678901','北京市昌平区');
DAO测试
//注意:工具类需要从src中获取配置资源
//DBUtils.class反射对象调用,到资源目录src中获取配置文件的数据,返回IO流
//这种方式,在web中也能找的配置路径
InputStream is = DBUtils.class.getResourceAsStream("/db.properties");
p.load(is);
public class AdminDaoImpl implements AdminDao {
private QueryRunner runner = new QueryRunner();
@Override
public Admin selectByName(String name) throws SQLException {
String sql = "select * from admin where username=?";
return runner.query(DBUtils.getConnection(),sql,new BeanHandler<>(Admin.class),name);
}
@Override
public List<Admin> selectAdmins() throws SQLException {
String sql = "select * from admin";
return runner.query(DBUtils.getConnection(),sql,new BeanListHandler<>(Admin.class));
}
public static void main(String[] args) throws SQLException {
List<Admin> admins = new AdminDaoImpl().selectAdmins();
System.out.println(admins);
}
}
登录功能
业务层处理:在业务层完成登录功能,并加入事务
public Admin login(String name, String password) {
DBUtils.begin();
Admin res = null;
try {
Admin admin = adminDao.selectByName(name);
if(admin!=null&&admin.getPassword().equals(password)){
res = admin;
}
DBUtils.commit();
}catch (Exception e){
e.printStackTrace();
DBUtils.rollbock();
}
return res;
}
controller层接收前端参数,并调用servce层
@WebServlet("/login")
public class AdminController extends HttpServlet {
private AdminService adminService = new AdminServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理乱码问题
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//从前端获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
Admin login = adminService.login(username, password);
if(login==null){
resp.getWriter().write("登录失败!");
}else{
resp.getWriter().write("登录成功!");
}
}
}
五、总结与作业
总结
1.Http协议
概述-底层是tcp协议;特点-客户端与服务器模式,无连接,无状态(重点)
通讯协议,请求报文,响应报文
2.Servlet详解
访问方式-实现Servlet接口,继承GenericServlet,继承HttpServlet
配置属性:/路径 精确匹配,通配符匹配;自启动过程
注解方式配置(重点)
3.Servlet应用(重点)
请求方式:get和post请求
request和response对象
4.综合应用案例(重点)
Servlet+JDBC+HTML
作业
参考登录案例,使用当前admin表,完成注册功能(dao层只需完成添加功能,无需判断用户名是否存在)
晨考
1. 访问Servlet路径: http://localhost:8080/myweb/myservlet中,myweb是什么目录
myservlet是什么路径?
myweb:标识项目的上下文目录
servlet的真实映射路径
2.tomcat的默认端口是什么
8080
3.Servlet,GenericServlet,HttpServlet都是处理__动态web资源____的类;Servlet是__接口____,GenericServlet是__抽象类______,而HttpServlet是GenericServlet的___子类_______。
4.下列哪一个XML标签表示某一个Servlet的类 D
A.<servlet类>com.abciinc.OrderServlet.class</servlet class>
B.<class>com.abcinc.OrderServlet</class>
C.<servlet>com.abcinc.OrderServlet</servlet>
D.<servlet-class>com.abcinc.OrderServlet</servlet-class>
5.http的底层协议是什么?
TCP
6.tomcat中的web.xml与项目中的web.xml的区别?tomcat是全局默认的访问路径的配置 项目是局部的访问路径