文章目录
什么是Servlet
Servlet就是运行在web服务器上的一个小的java程序,用于处理从web客户端发送的请求,并对请求做出响应。
使用Servlet
- 编写一个java类实现Servlet接口
- 配置Servlet(web.xml)
<!-- 配置Servlet -->
<servlet>
<!-- 配置Servlet -->
<servlet-name>LoginServlet</servlet-name>
<!-- 配置Servlet类的全路径 -->
<servlet-class>com.itheima.controller.LoginServlet</servlet-class>
</servlet>
<!-- 配置Servlet的映射 -->
<servlet-mapping>
<!-- 配置Servlet -->
<servlet-name>LoginServlet</servlet-name>
<!-- 配置访问路径 -->
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
Servlet执行流程
Servlet的实现关系
- 基本的实现关系
Servlet接口——GenericServlet类(通用的Servlet,是一个与协议无关的Servlet)——HttpServlet类(Http专用的Servlet) - eclipse配置servlet
eclipse新建servlet——默认继承HttpServlet类——去掉勾选构造方法——完成——自动配置web.xml
旧版本的servlet确实需要手动配置web.xml文件,但是servlet2.5以后,servlet的配置直接在Java代码中进行注解配置(@WebServlet)。
Servlet的生命周期
servlet在第一次访问的时候会被实例化,只要一被实例化那么servlet中的init方法就会执行(init一个生命周期只执行一次)。任何一次从客户端发送来的请求,servlet中的service方法就会执行(在service方法内部根据请求的方式不同调用不同的DOPOST、get方法)。当servlet从服务器中移除或者服务器关闭的时候servlet对象销毁,里面的destory方法就会执行,然后垃圾回收就会将其回收掉。
Servlet的启动时加载
servlet默认在第一次访问的时候创建对象,现在通过一个配置将servlet的实例化的过程放在服务器启动的时候,让服务器启动时即创建Servlet对象。
在web.xml文件配置load-on-startup,数字写1以上的整数。
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.itheima.controller.InitServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
Servlet中url-pattern的配置方式
//完全路径匹配:以 / 开始,比如:/servlet、/aaa/servlet
//目录匹配:以/开始,以/*结束,比如:/*、/aaa/*
//扩展名匹配:以*开始,比如:*.jsp、*.aaa
// *代表任意字符
//访问的优先级:完全路径匹配>目录匹配>扩展名匹配
ServletContext对象
在服务器启动时为每个web项目创建一个单独的ServletContext对象,一个web项目只有一个此对象。
-
获取web项目信息
- 获取文件的mime类型:
ServletContext servletContext = this.getServletContext(); String mimeType = servletContext.getMimeType("aa.txt");
- 获取请求路径的工程名
String path = servletContext.getContextPath();
- 获取全局初始化参数(先在web.xml配置)
String username= servletContext.getInitParameter("username");
- 读取web项目下的文件
Properties properties = new Properties();
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
properties.load(is);
//获取数据
String url = properties.getProperty("url");
ServletContext作为域对象存取数据
域对象:指的是将数据存入到域对象中,这个数据就会有一定的作用范围。域指的是一定的作用范围。
- 存入数据:setAttribute
- 获取数据:getAttribute
- 移除数据:removeAttribute
ServletContext域对象作用范围:整个web项目。
Response对象的API
-
response关于响应行的方法
- setStatus()
-
response关于响应头的方法
- set开头的方法:针对一个key一个value的情况
- add开头的方法:针对一个key多个value的情况
-
response关于响应体的方法
- getWriter() 字符流
- getOutputStream() 字节流
-
response其他的API
- sendRedirect() 重定向
- setContentType 设置浏览器打开页面时采用的字符集
- setCharacterEncoding() 设置响应字符流的的缓冲区字符集
- addCookie() 服务器向浏览器回写cookie
Response对象的中文响应乱码处理
//使用字节流的方式输出中文
ServletOutputStream outputStream = response.getOutputStream();
//设置浏览器默认打开时候采用的字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
//设置中文转成字节数组字符集编码
outputStream.write("中文".getBytes("UTF-8"));
//设置浏览器默认打开时候采用的字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
//设置response获得字符流的缓冲区的编码
response.setCharacterEncoding("UTF-8");
//使用字符流输出中文
response.getWriter().print("中文");
//简化代码
response.setContentType("text/html;charset=UTF-8");
Request对象
浏览器向服务器提交数据的封装对象。
- request获得客户机的信息
//获得请求方式
System.out.println("请求方式:"+request.getMethod());
//获得客户机的IP地址
System.out.println("客户机IP地址:"+request.getRemoteAddr());
//获得请求参数的字符串
System.out.println("请求参数的字符串:"+request.getQueryString());
//获得请求路径的URL和URI
System.out.println("请求路径的URL:"+request.getRequestURL());
System.out.println("请求路径的URI:"+request.getRequestURI());
- request获得请求头的信息
//获得请求头的信息
System.out.println("获得客户机浏览器类型:"+request.getHeader("User-Agent"));
- request对象接收表单参数
//单值获取
String username = request.getParameter("username");
//获取多值 例如:有多个爱好
String[] hobby = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobby));
//接收整个表单数据
Map<String, String[]> map = request.getParameterMap();
for(String key: map.keySet()) {
String[] value = map.get(key);
System.out.println(key+" "+Arrays.toString(value));
}
-
request对象中文乱码处理
- post方式产生乱码的原因:数据在请求体中,放入request的缓冲区中,缓冲区默认编码为ISO-8859-1(不支持中文)。将request的缓冲区编码修改即可。
//post方式设置缓冲区编码 request.setCharacterEncoding("UTF-8");
- get方式产生乱码的原因:get方式提交的数据在请求行的url后面,在地址栏上就已经进行了一次url的编码了。解决办法:先将存入到request缓冲区中的内容以ISO-8859-1的格式提取,再以UTF-8的编码解码。
//post方式设置缓冲区编码 request.setCharacterEncoding("UTF-8"); //get方式处理乱码 String name = request.getParameter("name"); String encode = URLEncoder.encode(name,"ISO-8859-1"); String decode = URLDecoder.decode(encode,"UTF-8"); //简化写法,利用string的构造方法 String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");