赞
踩
Servlet是运行在服务器端的Java应用程序
生命周期 | 谁来做 | 何时做 |
---|---|---|
实例化 | Servlet 容器 | 当Servlet容器启动或者容器检测到客户端请求时 |
初始化 | Servlet 容器 | 实例化后,容器调用Servlet的init()初始化对象 |
处理请求 | Servlet 容器 | 得到客户端请求并做出处理时 |
销毁 | Servlet 容器 | 当程序中的Servlet对象不再使用的时候,或者Web服务器停止运行的时候 |
package com.zjl.servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author: zjl * @datetime: 2024/4/10 * @desc: */ public class HelloServlet extends HttpServlet { public HelloServlet() { System.out.println("生命周期之——————创建实例"); } @Override public void init(ServletConfig config) throws ServletException { String mycharset = config.getInitParameter("mycharset"); System.out.println("初始化时加载配置中的参数为:" + mycharset); System.out.println("生命周期之——————初始化"); } //接收Get请求 @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("生命周期之——————处理请求"); req.setCharacterEncoding("UTF-8");//设置请求字符集编码 resp.setCharacterEncoding("UTF-8");//设置响应字符集编码 req.setAttribute("key","value");//将数据保存在request域,以键值对方式 req.getSession().setAttribute("sessionKey","sessionValue");//根据request获取所在的session会话,并向会话保存一个数据 req.getRequestDispatcher("welcome.jsp").forward(req,resp);//转发跳转页面 } //接收POST请求 @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("生命周期之——————处理请求"); } /*@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("生命周期之——————处理请求"); }*/ @Override public void destroy() { System.out.println("生命周期之——————销毁"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.zjl.servlet.HelloServlet</servlet-class> <init-param> <param-name>mycharset</param-name> <param-value>utf-t</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello.do</url-pattern> </servlet-mapping> </web-app>
@Override
public void init(ServletConfig config) throws ServletException {
String mycharset = config.getInitParameter("mycharset");
System.out.println("初始化时加载配置中的参数为:" + mycharset);
System.out.println("生命周期之——————初始化");
config.getServletContext();
config.getServletName();
}
域对象:是可以像Map一样存取数据的对象
这里的域指的是存取数据的操作范围是整个web工程
存数据 | 取数据 | 删除数据 |
---|---|---|
Map | put() | get() |
域对象 | setAttribute() | getAttribute() |
<!--context-param是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<!--context-param是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
//2、获取当前的工程路径,格式: /工程路径
System.out.println("当前工程路径:" + servletContext.getContextPath());
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为http://ip:port/工程名/ 映射到IDEA代码的web目录
*/
System.out.println("工程部署的路径是:" + servletContext.getRealPath("/"));
System.out.println("工程下imgs目录的绝对路径是:" + servletContext.getRealPath("/imgs"));
System.out.println("工程下imgs目录下1.jpg的绝对路径是:" + servletContext.getRealPath("/imgs/1.jpg"));
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext servletContext = getServletContext();
// System.out.println(servletContext);
System.out.println("保存之前Context1 中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
servletContext.setAttribute("key1", "value1");
System.out.println("Context1 中获取域数据key1的值是:" + servletContext.getAttribute("key1"));
}
POST请求有:
响应行
响应的协议和版本号
响应状态码
响应状态描述符
响应头
key : value 不同的响应头,有其不同的含义
响应体 ==> 就是回传给客户端的数据
响应码 | 说明 |
---|---|
200 | 表示请求成功 |
302 | 表示请求重定向 |
404 | 表示请求服务器以及收到了,但是你要的数据不存在(请求地址错误) |
500 | 表示服务器已经收到请求,但是服务器内部错误(代码错误) |
文件 | MIME类型 |
---|---|
超文本标记语言文本 | .html, .htm text/html |
普通文本 .txt text/plain | |
RTF文本 | .rtf application/rtf |
GIF图形 | .gif image/gif |
JDEG图形 | .jpeg, .jpg image/jpeg |
au声音文件 | .au audio/basic |
MIDI音乐文件 | .mid, .midi audio.midi, audio/x-midi |
RealAudio音乐文件 | .ra, .ram audio/x-pn-realaudio |
MPEG文件 | .mpg, .mpeg video/mpeg |
AVI文件 | .avi video/x-msvideo |
GZIP文件 | .gz application/x-gzip |
TAR文件 | .tar application/x-tar |
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");//会报错
方法名 | 作用 |
---|---|
getRequestURI() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的ip地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(多个值的时候使用)[如复选框] |
getMethod() | 获取请求的方式GET或POST |
setAttribute(key, value) | 设置域数据 |
getAttribute(key) | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
类别 | 表示 | 作用 |
---|---|---|
字节流 | getOutputStream() | 常用于下载(传递二进制数据) |
字符流 | getWriter() | 常用于回传字符串(常用) |
注意:两个流同时只能使用一个
使用了字节流,就不能再使用字符流了,反之亦然,否则就会报错
在Servlet中,设置了@WebServlet注解,当请求该Servlet时,服务器就会自动读取当中的信息
如果注解@WebServlet(“/category”),则表示该Servlet默认的请求路径为…/category,这里省略了urlPatterns属性名,完整的写法应该是:@WebServlet(urlPatterns = “/category”)
如果在@WebServlet中需要设置多个属性,必须给属性值加上属性名称,中间用逗号隔开,否则会报错.
若没有设置@WebServlet的name属性,默认值会是Servlet的类完整名称.
在servlet3.0以后,web.xml中对Servlet配置,同样可以在@WebServlet注解中配置.
属性名 | 类型 | 描述 |
---|---|---|
name | String | 指定Servlet 的 name 属性,等价于 。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 |
value | String[] | 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于标签。 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 标签。 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于标签。 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于 标签。 |
description | String | 该 Servlet 的描述信息,等价于 标签。 |
displayName | String | 该 Servlet 的显示名,通常配合工具使用,等价于 标签。 |
拦截所有访问web资源的请求或者响应(servlet、Jsp页面、HTML页面),从而实现我们自己的业务逻辑,这些逻辑可以是实现访问权限的控制、过滤敏感词、压缩响应等功能。
过滤器是"链接"在容器的处理过程中的,它会在servlet处理器之前访问进入的请求,并且在响应信息返回客服端之前访问这些响应信息。这样就可以动态的修改请求和响应中的内容。
package com.zjl.filter; import javax.servlet.*; import java.io.IOException; /** * @author: zjl * @datetime: 2024/4/10 * @desc: */ public class MyCharsetFilter implements Filter { private String encode; public MyCharsetFilter(){ System.out.println("生命周期之——创建"); } @Override public void init(FilterConfig filterConfig) throws ServletException { encode = filterConfig.getInitParameter("encode"); System.out.println("生命周期之——初始化"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("生命周期之——执行过滤"); servletResponse.setCharacterEncoding(encode); servletRequest.setCharacterEncoding(encode); filterChain.doFilter(servletRequest,servletResponse);//执行过滤 } @Override public void destroy() { System.out.println("生命周期之——销毁"); } }
<filter>
<filter-name>mycharset</filter-name>
<filter-class>com.zjl.filter.MyCharsetFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>mycharset</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意Filter中在写拦截所有路径的时候只能写成/*,而不能写成/,因为写成/它就不走拦截器中的doFilter方法了。
在Servlet中/*即会拦截动态资源又会拦截静态资源,而/不会拦截动态资源
属性 | 作用 |
---|---|
FORWARD | 表示当前过滤器只会拦截由一个Servlet通过RequestDispatcher的forward()完成跳转 |
INCLUDE | 表示当前过滤器只会拦截由一个Servlet通过RequestDispatcher的include()完成跳转 |
REQUEST | 表示当前过滤器会拦截普通请求,但对于forward()与include()的跳转不进行拦截,REQUEST是默认的。 |
ERROR | 表示当跳转到指定的错误处理页面时,这个跳转请求会被当前过滤器拦截 |
多个过滤器会形成过滤器链
在Servlet中有两个Map,这两个Map的key均为Servlet注册时的值,但value是不同的。第一个Map的value是Servlet实例对象的引用,第二个Map的value为的值,即Servlet类的全限定类名。
当对Servlet的请求到达Servlet容器时,会先对请求进行解析,使用该解析出的URL,作为比较对象,从第一个Map中查找是否有匹配的key,若不存在匹配的key,那么读取其value,即Servlet对象的引用,执行该Servlet的service()方法。
若不存在匹配的key ,那么再从第二个Map中查找是否有匹配的key。若存在,这读取其value,即读取其value,即要访问的Servlet的全限定类名。然后使用反射机制创建该Servlet实例,并将该实例写入到第一个Map中,然后在执行该Servlet的service()方法。
若第二个Map中也没有找到匹配的key,那么就跳转到错误处理页面404。
一个数组与一个Map :
当对某资源的请求到达Web容器时,会先对请求进行解析,使用解析出的URI作为比较对象,从Map中查找是否存在相匹配的key。若存在,那么读取其value,即Filter对象的引用,将该应用存入到数组中。然后继续向后查找,直到将Map查找完毕。这样在数组中就会存在按照查找顺序排好序的Filter引用。
数组初始化完毕后,开始按照数组元素顺序进行执行。所有数组中的Filter全部执行完毕后,再跳转到请求的目标资源。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。