文章目录
- 一、Servlet的简介
- 二、Servlet的入门案例
- 三、创建Servlet的三种方式
- 3.1实现Servlet接口的方式
- 3.2继承GenericServlet抽象类的方式
- 3.3继承HttpServlet的方式
- 四、Servlet注解和配置文件的写法
- 4.1配置文件的写法
- 4.2注解的写法
- 五、Servlet的生命周期
- 六、Servlet获取前端请求的参数
- 七、通过前端发送数据到servlet,然后存入到数据库
- 八、中文乱码的解决方案
- 九、重定向和转发【重要】
- 9.1重定向
- 9.2转发
- 十、URL匹配规则
- 十一、ServletContext【重要】
- 十二、Request对象
- 十三、Response对象
- 十四、Cookie和Session
- 14.1会话技术
- 14.2Cookie
- 14.3Session
- 总结
一、Servlet的简介
Servlet ===>server applet
java服务器的小程序,是javaweb非常重要的环节。主要作用是完成html和java后台代码的交互(请求 《=》响应)
servlet是需要运行在Java服务器(Tomcat)中的,符合http协议的servlet的核心类接口的
javax.servlet和javax.servlet.http
javax.servlet.ServerException
javax.servlet.http.HttpServlet
javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpServletResponse
javax.servlet.http.Session
javax.servlet.http.Cookie
二、Servlet的入门案例
代码如下(示例):
package com.qfedu.a_servelt;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(name = "HelloServlet")** 告诉服务器这个是我的servlet* @webServlet 是我们请求servlet的入口* 把name去掉 然后加一个斜线,如果这个斜线没有带会报错 404* 请求这个servlet这个资源的时候* url : http://localhost:8080/day39_xkh/HelloServlet* */
@WebServlet("/HelloServlet")//这个是注解,是修饰下面的HelloServlet
//如果想要初始化这个类,必须写这个入口
public class HelloServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//我不管你的请求方式是get还是post请求doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置网页字符编码集response.setContentType("text/html;charset=utf-8");//请求和响应PrintWriter 打印写入 这种写法会在浏览器中显示出来response.getWriter().append("我的第一个web程序");System.out.println("hello,world");}
}
结果如下(示例):
红色的是日志信息
三、创建Servlet的三种方式
①实现Servlet接口的方式
① 返回值:void 方法名: init(ServletConfig servletConfig)throws ServletException : 使用ServletConfig对象初始化我们的Servlet ,这个方法执行
②返回值:ServletConfig 方法名: getServletConfig() :获取配置信息对象的方法,这个方法不执行
③void service(ServletRequest servletRequest,ServletResponse servletResponse) throws ServletException,IOException :核心方法,这个里面类似于我们的doget方法和dopost方法,这个方法一定执行
④String getServlrtInfo() :获取Servlet详细信息的方法,不执行
⑤void destory() : 在tomcat关闭的时候,进行销毁这个servlet,只有在tomcat关闭的时候执行
init(ServletConfig servletConfig)throws ServletException : 使用ServletConfig对象初始化我们的Servlet ,这个方法执行
getServletConfig() :获取配置信息对象的方法,这个方法不执行
service(ServletRequest servletRequest,ServletResponse servletResponse) throws ServletException,IOException :核心方法,这个里面类似于我们的doget方法和dopost方法,这个方法一定执行
getServlrtInfo() :获取Servlet详细信息的方法,不执行
destory() : 在tomcat关闭的时候,进行销毁这个servlet,只有在tomcat关闭的时候执行
②继承GenericServlet抽象类
service(ServletRequest servletRequest,ServletReponse servletresponse)throws ServletException,IOException
③继承HttpServlet抽象类
3.1实现Servlet接口的方式
代码如下(示例):
package com.qfedu.a_servlet;import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;@WebServlet("/test1")
public class Servlet1 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {//s使用ServletConfig对象初始化我们的Servlet//执行了,从这个地方可以说明一个问题 Servlet已经被实例化了System.out.println("init方法执行");}@Overridepublic ServletConfig getServletConfig() {//获取servlet配置信息对象//没有执行System.out.println("getServletConfig方法执行");return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//核心方法 类似于我们的doGet()方法,和doPost()方法 请求和响应//一定执行的System.out.println("service");}@Overridepublic String getServletInfo() {//获取Servlet的详细信息//没有执行System.out.println("getServletInfo方法执行");return null;}@Overridepublic void destroy() {//当tomcat关闭的时候,执行销毁这个servlet的方法System.out.println("destroy方法执行");//只有当tomcat关闭的时候,才会执行这个方法}
}
结果如下(示例):
3.2继承GenericServlet抽象类的方式
代码如下(示例):
package com.qfedu.a_servlet;import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
/*
* 第二种方式:继承GenericServlet
*
* */
@WebServlet("/test2")
public class Servlet2 extends GenericServlet {//只有一个方法是必须重写的,抽象方法//为什么?service是核心方法,因为请求和响应就是执行这个方法@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//解决中文乱码问题servletResponse.setContentType("text/html;charset=utf-8");servletResponse.getWriter().append("我是第二种创建Servlet的方法");}
}
结果如下(示例):
3.3继承HttpServlet的方式
代码如下(示例):
package com.qfedu.a_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("/test3")
public class Servlet3 extends HttpServlet {//因为在前端的时候,有两种请求方式get和post//doGet和doPost方法写在了Service方法中了@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");resp.getWriter().println("我是HttpServlet创建的Servlet");}
}
结果如下(示例):
这三个创建方式选择哪个?
最好的方式是继承HttpServlet
1.可以减少对其他方法的要求 init destroy
2.可以根据前端的要求进行分门别类 doGet doPost
四、Servlet注解和配置文件的写法
1.上面采用的都是注解的写法,对Servlet的版本有要求,servlet3.0及以上的版本才可以使用注解
2.还有一种写法是配置文件的写法。对文件没有要求
4.1配置文件的写法
① 需要在web.xml文件写配置
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_3_1.xsd"version="3.1"><!-- servlet配置文件的写法--><servlet><display-name>WebXMLServlet</display-name>
<!-- servlet-name要和servlet-mapping所对应,映射的关系--><servlet-name>WebXMLServlet</servlet-name>
<!-- servlet-class 是servlet所对应的类--><servlet-class>com.qfedu.b_servlet.WebXMLServlet</servlet-class>
<!-- 只要tomcat服务器一启动就会加载这个类--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>WebXMLServlet</servlet-name><url-pattern>/Webxml.do</url-pattern></servlet-mapping>
</web-app>
java代码:
代码如下(示例):
package com.qfedu.b_servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class WebXMLServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置网页的编码格式resp.setContentType("text/html;charset=utf-8");resp.getWriter().append("我这个是配置文件的写法");}
}
结果如下(示例):
4.2注解的写法
代码如下(示例):
package com.qfedu.b_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;
/*** name是Servlet的名字 对应配置文件中的servlet-name* value 是servlet程序对应的url 只能写一个* loadOnStartup tomcat启动的时候会不会自动加载这个servlet类* 默认为 -1 (不加载) 1(自动加载)* urlPatterns对应配置文件中的url-pattern 可以写多个url,都可以访问** */
@WebServlet(name = "AnnotionServlet",urlPatterns = {"/as","/as.do","/as.action"},loadOnStartup = 1)
public class AnnotionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("这个是注解的写法");//设置网页的编码格式response.setContentType("text/html;charset=utf-8");response.getWriter().append("<div style=\"width: 300px;height: 200px;background-color: red\"><font style=\"color: blue;font-size: 30px\">仰天大笑出门去</font></div>");response.getWriter().append("<br><font style='color: red;font-size: 30px'>我辈岂是蓬蒿人</font>");}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
结果如下(示例):
【注意事项】:每一个servlet的名字(注解中的name属性或配置文件的servlet-name标签)都是唯一的,不同的servlet对象的名字不能相同,如果相同,访问的时候会报404的错误
前提:配置文件的写法的servlet-name和注解写法的name属性相同
结果:
五、Servlet的生命周期
详情请看:http://www.51gjie.com/javaweb/847.html
整个servlet在执行的过程中
1.constructor
2.init
3.service
4.destroy
阶段1:
servlet整个类对象进行实例化(在tomcat服务器中),提供给tomcat使用
阶段2:
servlet类对象的初始化
阶段3:
servlet对外提供服务,相当于我们的doGet和doPost
阶段4:
servlet进行销毁,可以主动申请关闭servlet,但是一般tomcat一关闭,servlet就自动销毁了
代码如下(示例):
package com.qfedu.b_servlet;import javax.servlet.ServletConfig;
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;
//loadOnStartup tomcat启动的时候是否会自动加载这个servlet这个实体类,1代表自动加载,-1不会自动加载(默认)
@WebServlet(value = "/life.do" , loadOnStartup = 1)
public class LifeCycleServlet extends HttpServlet {public LifeCycleServlet(){System.out.println("我是LifeCycleServlet的无参构造方法在执行");}@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);System.out.println("init方法进行初始化servlet类对象");}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");resp.getWriter().append("service在对外提供服务");System.out.println("service在对外提供服务");}@Overridepublic void destroy() {System.out.println("destroy在执行servlet的销毁");}
}
结果如下(示例):
前提:我把loadOnStartup的值设置为1(看上面的代码),就是tomcat一启动,servlet就会被加载
刚启动的时候
construct构造方法就已经执行
init初始化这个servlet类对象已经执行
html页面对servlet发出请求
servlet开始响应
service方法开始执行
关闭程序,tomcat关闭
destroy方法开始执行
六、Servlet获取前端请求的参数
学好Servlet必须紧紧围绕着请求和响应这两个概念
以上写的代码只是进行请求,然后再响应到客户端。请求的时候没有带数据给Servlet
下面开始写在请求的时候前端带数据到servlet里面,我们servlet要接收前端给我们的这个数据
第一步写一个html前端页面,在web文件夹中直接创建一个html,名字叫做Login
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="LoginServlet" method="get">姓名:<input type="text" name="user" /><br>密码:<input type="password" name="password" /><br><input type="submit" value="登录"></form>
</body>
</html>
第二步创建一个Servlet类
代码如下(示例):
package com.qfedu.c_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("/LoginServlet")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/** html页面中 input标签发送的数据,都会存到HttpServlet这个对象里面* 通过这个对象获取input输入框中的值user 是input标签中name属性的属性值* */*//这个getParameter方法就是获取请求对象的参数的,通过前端input标签name的属性值获取的//获取前端的数据,要注意中文乱码,当是post请求的时候,会出现乱码//设置字符编码request.setCharacterEncoding("utf-8");String user = request.getParameter("user");String password = request.getParameter("password");System.out.println("user: " + user+"===password"+password);}
}
结果如下(示例):
首先启动服务器,然后在url后面输入Login.html
进入登录页面,输入账号和密码(谁便写)
点击登录
结果:
七、通过前端发送数据到servlet,然后存入到数据库
类似于注册功能
1.先写一个html页面,主要发送数据给Servlet
2.写一个RegisterServlet,这个Servlet的目的获取前端传过来的数据
3.我们想办法把获取的数据存入到数据库
4.封装的JDBCUtil和BaseDao这里可以拿来使用,使用c3p0连接池还是druid连接池
5.复制粘贴过来
6.我想使用这个BaseDao这个类方法update
7.需要再写一个类去继承BaseDao,这个类(UserDao)是专门写sql处理的相关的类
8.在Servlet里面实例化UserDao调用UserDao下面的方法即可。
①先写一个注册页面register.html
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--提交到一个Servlet中不用带斜线-->
<!--如果是get请求,给Servlet的时候中文不会乱码但是是post请求的时候,中文会乱码
--><form action="RegisterServlet" method="post">姓名:<input type="text" name="user"><br>密码:<input type="password" name="password"><br><input type="submit" value="注册"></form>
</body>
</html>
②再写一个UserDaot类去继承我们封装的BaseDao
代码如下(示例):
package com.qfedu.a_servlet;import com.qfedu.util.BaseDao;import java.sql.SQLException;//采用MVC的架构思想
//dao层都是写sql处理增删改查的
public class UserDao extends BaseDao {public int addUser(Object[] objs) throws SQLException {String sql = "insert into user(name,password) values(?,?)";return super.update(sql,objs);}
}
③写一个RegisterServlet类继承HttpServlet类
代码如下(示例):
package com.qfedu.a_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;
import java.sql.SQLException;@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取前端传过来的数据//因为采取的是post请求,所以首先更改编码格式req.setCharacterEncoding("utf-8");String user = req.getParameter("user");String password = req.getParameter("password");//现在拿到了user,和password,把这两个数据存到数据库中//BaseDao baseDao = new BaseDao();//准备一个sql语句,还有准备参数,参数是一个吧数组//一般Servlet里面不让写sql语句 怎么办?这个确实能实现数据库数据的添加n//但是不规范,sql单独放在另外一个类中// String sql = "insert into user(name, password) values(?,?)";
// Object[] objs = {user, password};
// try {
// baseDao.update(sql, objs);
// } catch (SQLException e) {
// e.printStackTrace();
// }//把sql语句写在了另外一个类中UserDao userDao = new UserDao();Object[] objs = {user,password};try {userDao.addUser(objs);} catch (SQLException e) {e.printStackTrace();}}
}
④在java2109这个数据库中建一个user表
结果如下(示例):
第一步先启动程序,在url后面输入register.html,进入注册页面
输入姓名和密码,谁便输,点击注册
页面跳转到RegisterSevlet页面
打开数据库,查看user数据表
此时前端发送的数据就存入到数据库中了
八、中文乱码的解决方案
请求时候的乱码问题:
前端发送数据到Servlet,如果是post请求的话,input输入中文数据的时候,Servlet接到的数据是乱码的。
request.setCharacterEncoding(“utf-8”);
响应时候中文乱码的问题:
Servlet响应数据到客户端的时候,如果是中文的话,会乱码
response.setContentType(“text/html;charset=utf-8”);
九、重定向和转发【重要】
web网站上面有一些跳转按钮。比如登录成功以后跳转到主页面!!!
9.1重定向
用户通过浏览器发送一个请求,Tomcat服务器接收这个请求,会给浏览器发送一个状态码302,并设置一个重定向的路径,浏览器如果接收到了这个302的状态码以后,就会去自动加载服务器设置的路径
一个页面跳转到另外一个页面(应用场景)、登录页面跳转到主页面
denglu.html====>TestLoginServlet====>target.html
特征:
①重定向的过程是浏览器(客户端)的行为
②实际上浏览器做了2次请求(当点击登录按钮的时候做了两次请求)(分别是请求TestLoginServlet和target.html)
③注意上一次请求的request对象会丢失
④重定向有一个非常明显的特征,即浏览器的url变化了
⑤重定向可以重定向到网络的任意资源(比如京东淘宝等资源)
重定向就一句核心代码:
response.sendRedirect(“target.html”);就这一行代码,但是这一行代码必须写在doGet或者doPost方法中
1.先写一个登录页面,denglu.html
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="TestLoginServlet" method="post">姓名:<input type="text" name="user"><br>密码:<input type="password" name="password"><br><input type="submit" value="登录"></form>
</body>
</html>
2.写一个重定向的目标页面target.html
代码如下(示例):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>我是主页
</body>
</html>
3.写Servlet类TestLoginServlet.java
代码如下(示例):
package com.qfedu.b_servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class TestLoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置编码,因为前端页面采用的是post请求req.setCharacterEncoding("utf-8");//获取前端发送过来的数据String user = req.getParameter("user");String password = req.getParameter("password");//登录以后跳转到主页//重定向//这个TestLoginServlet里面的数据是不能传给target.html的resp.sendRedirect("target.html");}
}
结果如下(示例):
url发生了变化
9.2转发
用户发送数据请求到服务器,服务器接收当前请求,会调用内部方式(转发)处理该请求,最终把响应给客户端
特征:
①转发是服务器的行为
②浏览器在这个过程中只有一次行为
③转发可以带有数据 request对象中
④url不会发生任何的变化
⑤转发只能在当前项目中进行转发,不能转发外部资源
核心代码也只有一行
request.getRequestDispatcher(“TestServlet2”).forward(request,response);
这一行代码就表示进行了转发,url没有变,但是响应的结果却是另外一个Servlet里卖的东西
一次请求干了两个活
1.创建一个Servlet类,TestServlet1.java
代码如下(示例):
package com.qfedu.b_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("/TestServlet1")
public class TestServlet1 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("用户请求TestServlet1");//给当前的request对象设置一些数据,request对象带有数据//name = 猪肉形req.setAttribute("name","猪肉邢");/*** 可以通过request对象转发到其它资源(另外一个Servlet)里面* *///转发会将一个servlet里面数据带到另外一个Servlet里面req.getRequestDispatcher("TestServlet2").forward(req,resp);}
}
2.创建第二个Servlet类,TestServlet2.java
代码如下(示例):
package com.qfedu.b_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("/TestServlet2")
public class TestServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//TestServlet1里面转发过来的数据Object name = request.getAttribute("name");response.setContentType("text/html;charset=utf-8");response.getWriter().append("这个是转发到TestServlet2里面的name值:" + name);}
}
在弹出的网页中的url后面输入目标资源TestServlet1,点击回车键
结果如下(示例):
十、URL匹配规则
@WebServlet("/test") 中/test就是我们某一个资源的路径的写法
用户申请了一个资源:http://localhost:8080/day41_xkh/LoginServlet
①http协议
②localhost本地服务器主机的名字
③8080端口号
④day_xkh/LoginServlet是我们所申请的资源
day_xkh/当前应用程序目录,就是程序的绝对路径
LoginServlet申请的资源
URL匹配原则:
1.精准匹配
比如 /资源名字@WebServlet(“test/do”)
2.模糊匹配
精准匹配:
代码如下(示例):
package com.qfedu.a_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真实的值,去找到你所对应的资源
@WebServlet("/testServlet1")
public class TestServlet1 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().append("这个是精准匹配");}
}
结果如下(示例):
模糊匹配:
第一种 以.do后缀的模糊匹配
代码如下(示例):
package com.qfedu.a_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;//这个模糊匹配是以后缀是.do的资源
//进行匹配的时候在web应用程序下面,.do以前可以随意的填写,这样就可以找到这个资源了
//比如:
//注意*前面没有加斜线
//@WebServlet("*.do")
public class TestServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().append("这个是模糊匹配的一种,以.do后缀的匹配");}
}
结果如下(示例):
注意我的url中day42_xkh后面随便写的,最后是以.do结尾的就行
模糊匹配的另外一种写法,就是在/后面随意写就可以了!!!
//以后会用,在将过滤器的时候使用。
代码如下(示例):
package com.qfedu.a_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("/*")
public class TestServlet3 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().append("我这个是随意的资源访问五,url不管写什么都可以匹配到");}
}
结果如下(示例):
十一、ServletContext【重要】
ServletContext接口,实例化以后是一个对象,是我们当前应用程序可以使用的唯一对象
在一个Servlet里面,使用另外一个Servlet里提供的数据,怎么办?转发,但是不用转发怎么办?需要使用ServletContext对象,是全局的。比如,你在一个Servlet里面设置一个数据,想要在另外一个Servlet里面使用这个数据,没办法。但是可以通过ServletContext这个接口,这个对象是全局的。如果你在一个Servlet里面使用Servlet里面使用ServletContext对象设置一个数据,在另外一个Servlet里面也可以通过Servlet里面也可以通过ServletContext这个对象获取这个数据
两个Servlet依靠ServletContext对象进行通信,分享一些数据
代码如下(示例):
Servlet对象1
package com.qfedu.b_servletContext;import javax.servlet.ServletContext;
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("/context1.do")
public class ContextServlet1 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//要使用一个对象,这个对象可以实现Servlet之间的共享数据//1.获取servletContext对象即当前上下文对象 request.getServletContext()ServletContext servletContext = request.getServletContext();//2.给当前上下文对象设置一部分数据 setAttribute("键","值")servletContext.setAttribute("msg","我是context1对象");servletContext.setAttribute("person",new Person("张三",32));//返回当前Servlet的详细信息 getServletInfo()String serverInfo = servletContext.getServerInfo();//返回项目的根目录(以后出现404可以先找这个根目录然后再一点一点的找)//servletContext.getContextPath()String contextPath = servletContext.getContextPath();System.out.println(serverInfo);System.out.println(contextPath);}
}
Person类:
package com.qfedu.b_servletContext;public class Person {private String name;private int age;public Person(){}public Person(String name,int age){this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
Servlet对象2
package com.qfedu.b_servletContext;import javax.servlet.ServletContext;
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("/context2.do")
public class ContextServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");//处理响应时候乱码的问题//这个Servlet是获取当前上下文对象存放的数据//1.获取当前上下文对象ServletContext servletContext = request.getServletContext();Object msg = servletContext.getAttribute("msg");System.out.println(msg);Person person = (Person) servletContext.getAttribute("person");System.out.println(person);response.getWriter().append(" "+msg);}
}
结果如下(示例):
十二、Request对象
ServletRequest接口,用户访问服务器,服务器会生成一个对象包含了http所有请求头,由于使用的是http协议,HttpServletRequest
常用的方法
getRequestURL();获取的完整的URL,即统一资源定位符
getRequestURI();获取资源的名字,即统一资源标识符
getQueryString();获取一个url参数部分
getRemoteAddr();返回的是客户端的ip地址
getRemoteUser();返回的是客户端的用户
getRemotePort();返回的是客户端的主机的端口号
getRemoteHost();返回的是客户端的主机地址
getCookie();获取Cookie对象
getSession();获取Session对象
getLocalName();获取Web服务器主机的名字
getServletContext();获取上下文对象的
setCharacterEncoding();设置编码集的
getParameter();获取前端传过来的数据
setAttribute();将数据设置给request对象
geAttribute();获取request对象中的数据
代码如下(示例):
package com.qfedu.c_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("/request1")
public class RequestServlet1 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取一个完整的urlSystem.out.println(request.getRequestURL());//http://localhost:8080/day42_xkh/request1//获取资源的名字//比如:http://localhost:8080/day42_xkh/request1System.out.println(request.getRequestURI());//day42_xkh/request1//获取一个url的参数部分//比如 http://localhost:8080/day42_xkh/request1?user=goudan&password=123456System.out.println(request.getQueryString());}
}
结果如下(示例):
代码如下(示例):
package com.qfedu.c_request;import javax.servlet.ServletContext;
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("/request2")
public class RequestServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取客户端的ip地址System.out.println(request.getRemoteAddr());//获取客户端的主机地址System.out.println(request.getRemoteHost());//获取客户端的用户System.out.println(request.getRemoteUser());//获取客户端的主机的端口号System.out.println(request.getRemotePort());//以上代码如果你们在同一个网段是可以测试的//写完这个代码以后,你把ip地址告诉你室友,让他去访问你写的这个资源//http://10.8.199:8080/day41_wb/request2//发现打印的都是别人访问的东西。意味着从这地方知道,//你想黑军方的网站,是不可能,你在哪都能找到你,让后关起来,审判,枪毙//以后开发必用的!!!是以下的方法//获取前端传送过来的数据
// String name = request.getParameter("name");
// request.setCharacterEncoding("utf-8");//设置请求的编码集
// //转发
// request.getRequestDispatcher("target.html").forward(request,response);
// //给request这个对象设置数据
// request.setAttribute("name","狗蛋");
// //获取request对象的值
// request.getAttribute("name");
// //获取上下文对象
// ServletContext servletContext = request.getServletContext();}
}
结果如下(示例):
十三、Response对象
响应对象,把数据给客户端
我们的Servlet紧紧围绕着两个点(Request,Response)请求和响应
setHeader();设置响应头的参数
setContentType();设置字符编码集
getWriter();获取字符输出流对象
addCookie();对浏览器新增一个Cookie
sendRedirect();重定向
十四、Cookie和Session
http是一种无状态的访问
浏览器发送请求到服务器,服务器给与一定的响应,但是断开连接以后,如果服务器没有发送任何请求,是没有任何响应的
这个就是无状态的访问:
实际操作中存在一定的问题:
比如登录一个网站以后,再次跳转到这个网站的其它页面,他是不会保存第一个页面的状态的,这叫无状态的。
登录一个页面的话,他不会保证上一页面的状态,如何来保持上一个页面的状态的呢?靠下面将要讲的会话技术(Cookie和Session),才能保持上一个页面的状态!!
如果没有cookie和session的话,http协议是一个无状态的协议,你每一个跳转到下一个页面的时候都是需要先登录才能使用,这样就很麻烦
比如淘宝(没有cookie和session的话),登录上去了,(需要登录才能)选择商品,(需要登录才能)放到购物车,(需要登录才能)然后购买,这样用户的体验是相当差的然后才有咱们即将要讲的会话控制。会话控制的目的就是为了点击页面的时候,保持上面一个页面的状态
14.1会话技术
Cookie:
浏览器保存的内容,通常cookie是在浏览器中保存的,每一次访问服务器的时候,浏览器会自动的把cookie带到下一个页面的
cookie的大小是有限制的,通常是4096byte
cookie信息中不能有中文
cookie的保存是以键值对的形式存在的
Session:
保存服务器中,每一个session在我们当前的服务器会有一个标识号
会保存浏览器访问服务器的一些记录信息,没有大小的限制
可以保存中文
信息的保存也是以键值对的形式存在的
14.2Cookie
如果想要使用cookie要保证我们的浏览器是开启cookie,所以说有一定的弊端,如果浏览器关了,关了就不能再使用cookie了
1.cookie的构造方法,目的是实例化出来cookie对象
Cookie(String name,String value)
2.设置cookie的方法
setValue(String value);修改cookie的值
setMaxAge(int time);设置cookie的有效时间
setPath(String path);设置当前cookie的有效路径
3.要将cookie发送到浏览器
response.addCookie(Cookie cookie);
先给浏览器设置cookie,获取cookie,销毁cookie,获取cookie,销毁cookie
设置cookie
package com.qfedu.d_cookie;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.创建cookie对象//将键:java2109 值:shabi 实例出来,存到cookie对象中Cookie cookie = new Cookie("java2109", "shabi");//2.设置有效时间,如果不设置有效时间,没有关闭浏览器,cookie会一直存在的/** 正数:表示当前cookie的有效时间* 负数:表示当前浏览器打开的时候存在,关闭的时候没了* 0:销毁当前的cookie* */cookie.setMaxAge(60*60*24);//设置了有效期是个正数,// 即使关闭了浏览器,也可以获取cookie,可以自动登录的东西
// cookie.setPath("day42_xkh");//当前项目,所有的Servlet都有这个cookie//3.把cookie发送到浏览器response.addCookie(cookie);}
}
获取cookie
package com.qfedu.d_cookie;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取浏览器中cookie,返回值是一个数组Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {//两个//JSESSION//java2109//浏览器一旦关闭cookie就没了System.out.println(cookie.getName());//获取键System.out.println(cookie.getValue());//获取值System.out.println("==============");}}
}
销毁cookie
package com.qfedu.d_cookie;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/destroyCookie")
public class DestroyServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//退出登录Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {//JSESSION//java2109if (cookie.getName().equals("java2109")){cookie.setMaxAge(0);//销毁cookie//重新发送给浏览器response.addCookie(cookie);}}}
}
14.3Session
为什么使用session?
1.cookie保存数据类型是单一的,只能保存字符串类型的数据,不能有中文
2.cookie的大小由限制
session可以解决以上cookie的问题
在java中session一般结合cookie使用
①使用session的时候一般要开启cookie
②如果浏览器没有开启cookie功能,我们可以通过html的url传参完后session的使用
getSession();获取session对象的
getId();JSESSIONID(在cookie里面)服务器下面一个标识号,session存在服务器中其中JSESSION是服务器下面的一个标识
invalidate();销毁session
setMaxInactiveInterval();设置过期时间
setAttribute();设置session的内容
getAttribute();获取session的内容
往session里面存值;取值,销毁,再取值。让下一页面可以获取到session里面来保持下一个页面的状态
比如登录以后,用户名存到session,在我们跳转到主页,在主页里面可以把session里面用户名字取出来展示到我们的主页上
1.创建Session:
package com.qfedu.a_session;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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/setSession")
public class SessionTestServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取session对象HttpSession session = request.getSession();System.out.println(session);//获取的是JSESSIONID 服务器唯一的标识System.out.println(session.getId());//给session设置一个时间,有效果的,里面放的是秒session.setMaxInactiveInterval(60*60*24);session.setAttribute("name","张三");}
}
2.获取Session:
package com.qfedu.a_session;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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/getSession")
public class GetSessionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取Session对象//第一次创建session的时候默认为true//false的话,这个session使用的是已经创建好的session对象HttpSession session = request.getSession(false);//2.获取session,通过键取值Object name = session.getAttribute("name");System.out.println(name);}
}
3.销毁Session:
package com.qfedu.a_session;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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/destroySession")
public class DestroySessionServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取session对象HttpSession session = request.getSession(false);//销毁当前的sessionsession.invalidate();}
}
总结
提示:这里对文章进行总结:没有总结