Servlet简介
servlet 是运行在服务器端的Java程序; 负责处理浏览器请求 和 响应请求;
Servlet 接口方法
public class ServletTest implements javax.servlet.Servlet {
//初始化方法 : 只执行一次
@Override
public void init(ServletConfig servletConfig) throws ServletException { }
//每次访问Servlet资源 ,都会被执行一次
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException
{ System.out.println("hello"); }
//程序正常关闭时, 执行一次
@Override
public void destroy() { }
Servlet接口的体系结构
Servlet -- 接口|| 实现|GenericServlet -- 抽象类|| 继承|HttpServlet -- 抽象类* GenericServlet :将 Servlet 接口中其他的方法做了默认空实现,只将 service() 方法作为抽象* 将来定义 Servlet 类时,可以继承 GenericServlet ,实现 service() 方法即可* HttpServlet :对 http 协议的一种封装,简化操作1. 定义类继承 HttpServlet2. 复写 doGet/doPost 方法
创建Servlet 程序 : 继承HttpServlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":" + password);
UserMapper userMapper = new UserMapper();
User user = userMapper.getUserToLogin(username, password);
if (user != null) {
req.getSession().setAttribute("user",user);
resp.sendRedirect("/java_web/jsp/index.jsp");
} else {
req.setAttribute("msg", "用户名或密码错误");
req.getRequestDispatcher("Login.jsp").forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
Servlet 的生命周期
-
初始化 阶段 : 执行 init 方法,只执行一次 。 说明一个 Servlet 在内存中只存在一个对象, Servlet 是单例的
可以配置执行 Servlet 的创建时机。* 在 <servlet> 标签下配置1. 第一次被访问时,创建* <load-on-startup>的值为负数2. 在服务器启动时,创建* <load-on-startup>的值为 0 或正整数
-
运行阶段 : 执行 service 方法,执行多次
- 销毁阶段 : 执行destroy方法,只执行一次。只有服务器正常关闭时,才会执行destroy方法。
Servlet请求和响应原理 :
-
tomcat 服务器 会根据请求 url 中的资源路径 , 创建相应的 Servlet 对象 ;
-
tomcat服务器 会创建 request 和response 对象;
-
tomcat 将 request 对象 和 response 对象 作为参数传递给 service() 方法 ; 并且 调用 service() 方法
-
我们 通过重写方法 可以 通过 request 对象获取请求数据 , 并通过 response 对象 设置响应信息tomcat 服务器 从 response 对象中 读取响应信息 并 返回给浏览器 .
ServletContext 接口
1
、
ServletContext
是一个接口,它表示
Servlet
上下文对象
2
、
一个
web
工程,只有一个
ServletContext
对象实例
,
被所有
Servlet
对象共享。
3
、
ServletContext
对象是一个域对象。
4
、
ServletContext
是在
web
工程部署启动的时候创建。在
web
工程停止的时候销毁
-
获取 Web 工程 初始化参数
System.out.println("servlet执行了");
ServletContext servletContext = getServletContext();
System.out.println("帐号:" +servletContext.getInitParameter("user"));
System.out.println("密码" + servletContext.getInitParameter("password"));
//servlet执行了 //帐号:cjc //密码root
- 实现多个Servlet对象 共享数据
什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个 web 工程。
//context对象 存储数据
servletContext.setAttribute("data","this servlet save data");
存储数据后, 只要当前 工程没有销毁, 无论在那个Servlet程序中都可以访问到这个数据
-
读取 Web 应用下的资源文件
/读取Web应用下的资源文件
System.out.println( "当前工程路径:" + servletContext.getContextPath() );
// 3、获取工程部署后在服务器硬盘上的绝对路径 // /***/ 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到 IDEA 代码的 web 目录<br/> */
System.out.println("工程部署的路径是:" + servletContext.getRealPath("/"));
request对象和response对象
request
对象和
response
对象的原理
1. request和
response
对象是由服务器创建的。我们来使用它们
2. request对象是来获取请求消息,
response
对象是来设置响应消息
Request 对象
-
作用 : 封装 HTTP 请求消息
-
原理 : 每次请求进来, Tomcat 服务器都会创建一个 Request 对象传 递给 Servlet 程序去使用 , 我 们可以通过 Request 对象,获取到所有请求的 信息。
- 获取请求参数数据
1. String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
2. String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
3. Enumeration<String> getParameterNames():获取所有请求的参数名称
4. Map<String,String[]> getParameterMap():获取所有参数的map集合
-
数据共享
//域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
void setAttribute(String name,Object obj):存储数据
Object getAttitude(String name):通过键获取值
void removeAttribute(String name):通过键移除键值对
// 注 : 只要是同一个reques对象, 所有的servlet程序都可以共享request域中的对象
Response对象
作用
:
封装
HTTP
响应消息
原理
:
每次请求进来,
Tomcat
服务器都会创建一个
Response
对象传 递给
Servlet
程序去使
用。我们可以通过
response
对象 设置响应消息
设置状态码:setStatus(int sc) 设置响应头:
setHeader(String name, String value) 设置响应体:
* 字符输出流:PrintWriter getWriter()
* 字节输出流:ServletOutputStream getOutputStream()
// PrintWriter out = response.getWriter();
// out.println("我是回传的数据");
Filter过滤器
Filter
过滤器:拦截请求,过滤响应
一般用于完成通用的操作
;
如 登录验证
.
统一编码处理
,
敏感字符过滤
.
创建Filter 程序 :实现Filter接口
1. 定义一个类,实现接口 Filter2. 复写方法3. 配置拦截路径1. web.xml2. 注解
- 字符编码过滤器:CharacterEncodingFilter
@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
filterChain.doFilter(request,response);
}
}
- 登录权限过滤器:LoginFilter
@WebFilter("/vip/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
User user =(User)req.getSession().getAttribute("user");
// 未登录
if (user == null) {
resp.getWriter().println("尚未登录,请登录");
resp.setHeader("refresh","3;url=/java_web/Login.jsp");
return;
}else {
filterChain.doFilter(request,response);
}
}
}
过滤器执行流程
请求和响应 都要经过过滤器
- 执行过滤器
- 执行放行后的资源 // chain.doFilter(request,response)
- 回来执行过滤器放行代码下边的代码
过滤器 配置路径问题
拦截路径配置:1. 具体资源路径: /index.jsp 只有访问 index.jsp 资源时,过滤器才会被执行2. 拦截目录: /user/* 访问 /user 下的所有资源时,过滤器都会被执行3. 后缀名拦截: *.jsp 访问所有后缀名为 jsp 资源时,过滤器都会被执行4. 拦截所有资源: /* 访问所有资源时,过滤器都会被执行
过滤器链(配置多个过滤器)
* 执行顺序:如果有两个过滤器:过滤器 1 和过滤器 21. 过滤器12. 过滤器23. 资源执行4. 过滤器25. 过滤器1* 过滤器先后顺序问题:1. 注解配置:按照类名的字符串比较规则比较,值小的先执行* 如: AFilter 和 BFilter , AFilter 就先执行了。2. web.xml配置: <filter-mapping> 谁定义在上边,谁先执行