文章目录
Servlet的简单入门
-
创建web项目,导入Servlet的依赖坐标
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
-
定义一个类,实现Servlet接口,并且重写接口中所有的方法,并在service方法中输入一句话
public class ServletDemo1 implement Servlet{ public void service(){} }
-
配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("demo1") public class ServletDemo1 implement Servlet{
-
访问,启动Tomcat,浏览器输入URL,访问该Servlet
Servlet的执行流程
- Servlet是由web服务器创建的,而Servlet方法也是由web服务器调用的
- 我们自己定义的Servlet函数,需要去继承Servlet接口,这样子web服务器就知道你需要去调用这些方法
Servlet的生命周期
- 加载和实例化:当Servlet第一次被访问时,由容器创建Servlet
- 初始化 :在Servlet实例化以后,容器将调用Servlet的
init()
方法初始化这个对象,完成一些加载配置文件、
创建连接等初始化的工作,该方法只调用一次。 - 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的
Service()
方法对请求进行处理 - 服务终止:当需要释放内存或者关闭容器时,容器就会调用Servlet实例的
destroy()
方法完成资源的释放。
例子讲解
init()
- 默认情况下,Servlet被第一次访问时,调用
loadOnStartup
- 默认的调用次数是:1次
service()
- 调用时机:每一次Servlet被访问时调用
- 次数:多次
destroy()
- 调用时机:内存释放或者服务器关闭的时候,Servlet对象被销毁时调用
- 次数:1次
其它的方法
-
getServletInfo()
-
getServletConfig()
Servlet的体系结构
由于开发BS架构的web项目,都是针对http协议的,所以,只要继承HttpServlet即可,然后实现doGet()
和 doPost()
方法即可。
HttpServlet中根据请求方式的不同,需要调用不同的办法,原因就是不同的请求方式拥有不同的请求参数,在httpSrevlet一共有七种请求方式。
而HttpServlet是通过继承GenericServlet,并且在service方法,将req以及resp强转为http开头的servlet对象,然后调用servlet方法,判断是什么请求方式,然后调用不同的doxxx()
方法。
ServletConfig
//1、获取初始化参数的API
//霍得ServletConfig对象
ServletConfig config = this.getServletConfig();
String username = config.getInitParameter("username");
String password = config.getInitParameter("password");
System.out.println(username+": "+password);
//2、获取所有的初始化参数的名称
Enumeration<String> names = config.getInitParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String value = config.getInitParameter(name);
System.out.println(name+":"+value);
}
//3、获取Servlet的名称
String servletname = config.getServletName();
System.out.println(servletname);
ServletContext
1、获取初始化参数
//1.1、获取ServleyContetxt
ServletContext servletcontext = this.getServletContext();
String mimeType = servletcontext.getMimeType("aa.txt");
System.out.println(mimeType);
//1.2、获取请求路径的工程名
String path = servletcontext.getContextPath();
System.out.println(path);
//1.3、获取全局初始化参数
String name = servletcontext.getInitParameter(username);
String word = servletcontext.getInitParameter(password);
System.out.println(name+";"+word);
2、读取web项目下的文件
//传统方式io,不能读取web的文件(路径是相对路径),找不到文件的路径(这个是在tomcat的bin文件夹下就可以)
Properties properties = new Properties();
//创建一个文件的输入流
InputStream is = new FileInputStream("src/main/java/db.properties");
//采用getResourceAsStream,获取绝对路径,读取文件的内容
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
//采用getRealPath,获取
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
System.out.println(path);
InputStream is = new FileInputStream(path);
properties.load(is);
//获取数据
String driverClassName =properties.getProperty("driverClassName");
String url =properties.getProperty("url");
String username1 =properties.getProperty("username");
String password1 =properties.getProperty("password");
//打印
System.out.println(driverClassName);
System.out.println(url);
System.out.println(username1);
System.out.println(password1);
3、ServletContext作为域对象存取数据
域对象:指的是将数据存入到域对象中,这个数据就会有一定的作用范围。域指的是一定的作用范围。
作用范围:servletcontext是在服务器启动的时候为每个web项目单独创建一个servletcontext对象,当web项目从服务器中移除,或者关闭服务器的时候,该对象就会销毁,所以在servletcontext中保存的数据会一直存在,直到服务器关闭。
ServletContext 作为域对象的API:
- 存入数据的方法:
setAttribute(name, word)
- 获取数据的方法:
getAttribute(name)
- 移除数据的方法:
removeAttribute(name)
urlPattern的配置
- servlet要被访问,必须配置访问路径(urlPattern)
- 一个servlet 可以配置多个urlpattern
@WebServlet(urlPatterns = {"/demo1","/demo2"})
- urlpattern的配置规则
- 精确匹配(优先级最高)
- 配置路径 == 访问路径
- 目录匹配
- 配置路径
@WebServlet(value = "/demo/*")
- 访问路径
localhost:8080/java/demo/aaa
- 配置路径
- 扩展名匹配
- 配置路径
@WebServlet(value = "*.xxx")
记住不能加上/ - 访问路径
localhost:8080/java/demo/xxx
- 配置路径
- 任意匹配
- 配置路径
@WebServlet(value = "/*")
或者@WebServlet(value = "/")
- 访问路径
localhost:8080/java/auygscguisai
- 配置路径
/
和/*
的区别:- 当我们的项目的Servlet配置了
/*
,会覆盖掉tomact中的DefaultServlet,其它的urlPattern都匹配不上都会走这个Servlet - 当我们的项目配置了
/
,意味着匹配任意访问路径
- 当我们的项目的Servlet配置了
- 优先级 精确匹配 > 目录匹配 > 扩展名匹配 > /* > /
- 精确匹配(优先级最高)
- 一个servlet 可以配置多个urlpattern
XML配置Servlet
Servlet在3.0版本前只支持在XML文件中配置,3.0后可以使用注解进行配置
在web.xml文件中,配置
- 配置类名
- 编写Servlet类别c++
<servlet> <servlet-name>demo</servlet-name> <servlet-class>com.hugh502.ServletDemo1</servlet-class> </servlet>
- 编写Servlet类别c++
- 配置访问路径
- 在web.xml中配置该servlet
<servlet-mapping> <servlet-name>demo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping>
- 在web.xml中配置该servlet
在现在,注解方便太多了,太容易用了。
request & response
-
request ------获取请求数据
-
request的继承体系
- tomcat需要解析请求的数据,封装成
request
对象,所以需要定义实现类;并传递到service
方法 - 实现类继承自
httpServletRequest
,因此学习的重点,便自然而然在httpServletRequest
- tomcat需要解析请求的数据,封装成
-
请求数据分为三个流程:
- 请求行
GET(request-demo/req1?username=zangsan HTTP/1.1)getMethode()
:获取请求的方式: 这里是GETgetContextPathh()
:获取虚拟目录(项目的访问路径): /resquest-demogetRequestURL()
: 获取URL(统一资源定位符): http://localhost:8080/request-demo/req1getRequestURI()
: 获取URI(统一资源标识符): /request-demo/req1getRemotAddr()
:获取URI和URLgetQueryString()
: 获取请求路径后提交参数的字符串,例如,获取请求参数(GET方式): uesname=zhangsan&password=123
- 请求头
User-Agent:Mozilla/5.0 Chorme/107.0.5304.88
- 一个头对应一个值
getHeader(String name)
根据请求头的名称,获取值
- 一个头对应多个值
getHeaders(String name)
- 请求体
Username = hugh&password=502getlnputStream()
获取字节输入流getReader()
获取字符输入流
- 请求行
-
request获取请求参数
- GET方式
getQueryString()
- POST方式
getReader()
- 提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码
getParameterMap()
:获取所有参数Map集合,接收所有的值,兼容以下两者,数据存入mapgetParameterValues(String name)
:根据名称获取参数值(数组),一个名称对应多个值getParameter(String name)
:根据名称获取参数值(单个值),一个名称对应一个值
- 请求参数出现乱码
- request对象接收中文的数据,这个不一定会出现乱码,只有编码解码产生冲突,才会有
一般情况是需要从ISO-8859-1
转成UTF-8
,实际的生产中,用post的比较多。- Post的请求方式
request.setCharacterEncoding("UTF-8");
- Get的请求方式
String value = new String(name.getBytes("ISO-8859-8"));
- Post的请求方式
- request对象接收中文的数据,这个不一定会出现乱码,只有编码解码产生冲突,才会有
- GET方式
-
request作为域对象存取数据
- 存入数据的方法:
setAttribute(name, word)
- 获取数据的方法:
getAttribute(name)
- 移除数据的方法:
removeAttribute(name)
- 存入数据的方法:
-
-
response ------设置响应数据
-
响应行的方法
setStatus(int sc)
设置响应的状态码- 200 请求成功
- 302 重定向
- 304 查找本地缓存
- 404 不存在
- 500 内部错误
-
响应头的方法
- 一个key,对应一个value
setDateHeader(String name, long value)
setHeader(String name, String value)
setIntHeader(String name, int vaIntlue)
- 一个key,对应多个value,追加值
addDateHeader(String name, long value)
addHeader(String name, String value)
addIntHeader(String name, int vaIntlue)
- 一个key,对应一个value
-
响应体的方法
getOutputStream()
//字节流getwriter()
//字符流
-
其它的api
sendRedirect(String location)
设置重定向的方法serContextType()
设置浏览器打开页面的字符集
-
中文乱码的问题:要区分是字节流还是字符流
getOutputStream()
//字节流- 下面的代码,浏览器在显示的时候不一定会产生乱码,这个跟浏览器打开的默认的字符集有关
//字节流输出中文 ServletOutputStream outputStream = response.getOutputStream(); //设置中文转换成字节数组的字符集编码 outputStream.write("你好".getBytes());
- 保证不产生乱码,将中文的字符集与浏览器打开默认的字符集有关
//字节流输出中文 ServletOutputStream outputStream = response.getOutputStream(); //设置浏览器默认打开的时候采用的字符集 response.setHeader("Content-Type", "text/html;charst=UTF-8"); //设置中文转换成字节数组的字符集编码 outputStream.write("你好".getBytes("UTF-8"));
- 下面的代码,浏览器在显示的时候不一定会产生乱码,这个跟浏览器打开的默认的字符集有关
getwriter()
//字符流- 下面这个是一定会产生乱码的,字符流是具有缓冲区的,而response的缓冲区所采用的默认编码是ISO-8859-1,这个字符集不支持中文
//使用字符流输出中文 response.getWriter().println("你好");
- 下面是按照正常思考方式所书写的代码
//设置浏览器默认打开的时候采用的字符集 response.setHeader("Content-Type", "text/html;charst=UTF-8"); //设置response获得字符流缓冲区的编码 response.setCharacterEncoding("UTF-8"); response.getWriter().println("你好");
- 当然简化的代码也有
response.setContentType("test/html;charst=UTF-8"); response.getWriter().println("你好");
- 下面这个是一定会产生乱码的,字符流是具有缓冲区的,而response的缓冲区所采用的默认编码是ISO-8859-1,这个字符集不支持中文
-