Servlet
zzj
一、HTTP协议
客户端发给服务器的叫请求协议,服务器发送给客户端的叫响应协议
1.1 书写格式
http://12.0.0.1:8080/s01/ser01?name=zs
上面格式的名称分别为:http协议,服务器ip,服务器端口号,项目路径,资源路径,要传入的属性值。
1.2 http协议的特点
- 支持c/s模式
- 简单快速,灵活
- 无连接,http1.1 版本之后支持可持续连接,现在一般都是这个版本
- 无状态
1.3 http请求与响应
请求由三部分组成:请求行、请求头、请求正文。
响应由三部分组成:状态行、响应头、响应正文。
1.4 消息头
请求头
- Referer:该请求头指明请求从哪里来,可以通过这个看到当前网页的父类网页
响应头
- Location:地址,重定向到一个新的地址,常用于更新域名。
- Refresh:自动跳转
二、Tomcat服务器
2.1 Tomcat的特点
- 是复合javaee web标准的最小的web容器。
- 技术先进、性能稳定、免费,属于轻量级应用服务器。
2.2 Tomcat的端口
Tomcat的端口是可以更改的,在Tomcat安装目录下的conf文件夹中找到server.xml文件,默认是8080。
2.3 Tomcat的优化
- 指定使用NIO(同步非阻塞)模型来接受HTTP请求(Tomcat 8默认NIO)
- Tomcat以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大的提高Tomcat对静态文件的处理性能
- 给Tomcat配置HTTP压缩功能
- 关闭DNS查询
三、Servlet的实现
3.1 servlet定义
- servlet对象由servlet容器创建。常见的容器有:tomcat,jetty等等
- Servlet是一个接口
3.2 servlet版本
- 3.0之前需要使用者手动配置web.xml,优势在于解决硬编码,但是文件臃肿。
- 3.0之后使用注解@WebServlet(“资源路径”),优势在于配置简单。
3.3 servlet的实现
- 继承HttpServlet,重新里面的service方法。
- 在类上面设置注解:@WebServlet(“资源路径”)。
- 发布项目到Tomcat中。
- 访问方式:http://localhost:8080/s01/ser01 最后两个为自己设置的项目地址和类的资源地址。
@WebServlet("/ser02")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("你好。。。");
}
}
3.4 servlet的生命周期
- init:实例与初始化时期,第一次请求资源的时候执行,只要不重启服务器,那么只会执行一次。
- service:服务阶段,执行service()方法,每访问一次就会执行一次。
- destory:销毁阶段,servlet服务器正常关闭的时候执行,只会执行一次。
四、HttpServletRequest对象
**作用:**接受客户端发送过来的请求信息。
它是ServletRequest的子接口
4.1 获取请求参数
方法:request.getParameter(“名称”);
//通过表单进行提交
String name = request.getParameter("userName");
System.out.println(name);
System.out.println(request.getParameter("userPwd"));
4.2 请求乱码问题
//解决请求乱码问题
request.setCharacterEncoding("UTF-8");
//同时设置服务端与客户端的编码格式
response.setContentType("text/html;charset=UTF-8");
4.3 请求转发
是服务端跳转,地址栏不发生改变,只有一次请求,request作用域数据可以共享,请求转发只能转发到当前项目下的资源。
// 请求转发到页面
req.getRequestDispatcher("login.jsp").forward(req,resp);
// 请求到相同项目下的Servlet
req.getRequestDispatcher("ser07").forward(req,resp);
4.4 request作用域
在同一次请求中有效,只能request使用。
//设置域对象内容
request.setAttribute("msg","用户名不能为空");
//获取域对象内容
request.getAttribute("msg");
//删除域对象
request.removeAttribute("msg");
五、HttpServletResponse对象
作用:服务端向客户端输出数据。
5.1 响应数据
方法:getWriter():字符流,只能响应回字符
getOutputStream():字节流,能响应回一切数据
注意:两个不能同时使用;
使用字符流往客户端输出中文的时候会出现乱码情况,这个时候就要手动设置编码格式: response.setContentType(“text/html;charset=UTF-8”);
//同时设置服务端与客户端的编码格式
resp.setContentType("text/html;charset=UTF-8");
//字符输出流
PrintWriter writer=resp.getWriter();
writer.write("<h2>Hello 中国</h2>");
writer.flush();
writer.close();
//直接输出流
/*ServletOutputStream out=resp.getOutputStream();
out.write("<h2>Hello 中国</h2>".getBytes());
out.flush();
out.close();*/
5.2 响应乱码
直接使用:response.setContentType(“text/html;charset=UTF-8”);可以同时解决请求乱码和响应乱码问题。
5.3 重定向
服务端指导,客户端跳转行为;地址栏发生改变,存在两次请求,request作用域不共享。
// 重定向到页面
resp.sendRedirect("login.jsp");
// 请求到相同项目下的Servlet
resp.sendRedirect("ser07");
//重定向可以跳转到百度
resp.sendRedirect("http://www.baidu.com");
六、请求转发与重定向的区别
请求转发 | 重定向 |
---|---|
服务端跳转 | 服务端指导客户端跳转 |
请求一次 | 请求两次 |
地址栏不变 | 地址栏改变 |
共享request作用域 | 不共享request作用域 |
只能转发到同一项目下的资源 | 可以重定向到任意地方 |
七、Cookie对象
cookie是由服务端创建,存储在客户端的,是浏览器技术,比如说记住密码等。默认情况下关闭浏览器则cookie被销毁。
7.1 cookie的创建与发送
在服务端创建,创建好之后发送给客户端。
Cookie cookie=new Cookie("uName","zhangsan");
responce.addCookie(cookie);
Cookie cookie2=new Cookie("uPwd","123456");
responce.addCookie(cookie2);
7.2 服务端获取cookie值
通过遍历客户端回传的cookie数组实现。
//获取cookie数组
Cookie[] cookies = request.getCookies();
// 判断数组是否为空
if (cookies != null && cookies.length > 0) {
// 遍历cookie数组并输出
for (Cookie cookie : cookies){
System.out.println(cookie.getName());
System.out.println(cookie.getValue());
}
}
7.3 设置cookie失效时间
-
正整数
表示存放在本地磁盘当中,存活指定秒数。
-
负整数
表示只在浏览器中存活,关闭浏览器失效。
-
零
表示删除cookie。
Cookie cookie=new Cookie("aa","AA");
//cookie.setMaxAge(-1);
cookie.setMaxAge(20);
resp.addCookie(cookie);
//设置七天失效
Cookie cookie1 = new Cookie("name", "张三");
cookie1.setMaxAge(7*24*60*60);
resp.addCookie(cookie1);
8.4 cookie的路径
情况一:在当前项目中的资源可以访问(默认)
Cookie cookie1 = new Cookie("a1","A1");
cookie1.setPath("/s03"); //可以不设置,默认
resp.addCookie(cookie1);
情况二:在指定项目中的资源可以访问 (只能在项目名是/s04的项目下的资源能访问)
Cookie cookie2 = new Cookie("a2","A2");
cookie2.setPath("/s04");
resp.addCookie(cookie2);
情况三:在当前服务器中任意资源都可访问 (只要是放在同一服务器下的资源)
Cookie cookie3 = new Cookie("a3","A3");
cookie3.setPath("/");
resp.addCookie(cookie3);
情况四:在指定项目下的指定资源可以访问
Cookie cookie4 = new Cookie("a4","A4");
cookie4.setPath("/s04/cook02");
resp.addCookie(cookie4);
注意:若访问的路径包含了其它cookie的路径的时候,这个时候就会同时获取两个cookie,例如:路径为"/s04/cook02"的cookie可以包含路径为"/s04"的cookie。
8.5 cookie中注意点
-
cookie保存在当前浏览器中。不能跨浏览器,不能跨电脑。
-
cookie存在中文问题。若cookie中存在中文不解码的话会出现乱码问题。(不过这种方式已经过期了,一般不会存在这种情况,用户名或密码之类的一般都不会为中文)
创建cookie时,要编码:
String name="姓名"; String value="张三"; name = URLEncoder.encode(name); value = URLEncoder.encode(value); Cookie cookie=new Cookie(name,value); resp.addCookie(cookie);
获取cookie时要解码:
Cookie[] cookies = req.getCookies(); if(cookies!=null && cookies.length>0){ for (Cookie cookie:cookies){ String name = URLDecoder.decode(cookie.getName()); String value = URLDecoder.decode(cookie.getValue()); System.out.println("键:" + name + ",值:" + value); } }
-
cookie同名问题。新的cookie会覆盖原有的cookie。
-
浏览器中存放cookie是有一定上限的。
八、HttpSession对象
HttpSession是一个纯粹的接口,不存在父接口,它的底层是cookie,使用request.getSession();方法获取当前会话的session对象。
//若session对象存在,则获取;session对象不存在,则创建
HttpSession session=request.getSession();
8.1 JSESSIONID会话标识符
开启了会话,客户端就会创建一个JSESSIONID,并将它回传给服务端。
- 当jsessionid的值不存在,服务器会新建一个会话,并生成新的sessionid,返回给浏览器。
- 当jsessionid的值存在,服务器会判断sessionid是否存在。
- 若不存在,服务器会创建一个新的会话,并生成新的sessionid,返回给浏览器
- 若存在,则使用当前已有的会话
8.2 session域对象
在一次会话中数据是可以共享的,使用请求转发或者重定向都可以共享session域对象。可以有多次请求。
HttpSession session = req.getSession();
session.setAttribute("uName","admin");
//请求转发
//req.getRequestDispatcher("sess03").forward(req,resp);
//重定向
resp.sendRedirect("sess03");
String uName =(String) req.getSession().getAttribute("uName");
System.out.println("Session:"+uName);
8.3 session对象的销毁
-
默认到期时间(默认最大不活动时间)
Tomcat中默认是30分钟失效,
可以在Tomcat的解压目录conf目录下,对应的web.xml中修改 ,单位是分钟。
-
手动设置最大不活动时间(单位:秒)
获取最大不活动时间 session.getMaxInactiveInterval();
设置最大不不活动时间 session.setMaxInactiveInterval(秒数);
-
手动销毁
session.invalidate();
-
关闭浏览器
session底层依赖cookie,cookie默认关闭浏览器失效
-
关闭服务器
HttpSession session = req.getSession();
int sec = session.getMaxInactiveInterval();
System.out.println("最大不活动时间:" + sec);
session.setMaxInactiveInterval(15);
session.invalidate();
**注:**当过了15秒没有操作时,服务器便会创建一个新的jsessionid,并将这个回应给浏览器。
九、ServletContext对象
它又称为Application对象,当web容器启动时就会创建这个对象。
9.1 ServletContext对象的获取
-
通过request对象获取
ServletContext servletContext = request.getServletContext();
-
通过session对象获取
ServletContext servletContext = request.getSession().getServletContext();
-
通过servletConfig对象获取
ServletContext servletContext2 = getServletConfig().getServletContext();
-
直接获取
ServletContext servletContext3 = getServletContext();
9.2 常用方法
System.out.println("获取服务器的信息: " + servletContext.getServerInfo());
System.out.println("获取项目的真实路径: " + servletContext.getRealPath("/"));
9.3 ServletContext域对象
只要服务器不关闭,则该域中的数据一直共享。
ServletContext servletContext = request.getServletContext();
servletContext.setAttribute("name","zhangsan");
String name = (String) servletContext.getAttribute("name");
servletContext.removeAttribute("name");
十、servlet的四大域对象
-
page域对象
pageContext:只在同一个页面有效 。
-
request域对象
在一次请求中有效。请求转发有效,重定向无效。
-
session域对象
在一次会话中有效。请求转发和重定向都有效,session销毁后无效。
-
ServletContext域对象
application在整个程序中有效。关闭服务器之后无效。
十一、文件的上传与下载
11.1 文件的上传(用的较多)
11.1.1 前台界面
表单的提交方式一定要为post,还要设置enctype=“multipart/form-data”。
<form method="post" action="uploadServlet" enctype="multipart/form-data">
姓名:<input type="text" name="uname"><br>
文件:<input type="file" name="myfile">
<button>提交</button>
</form>
11.1.2 后台实现
除了使用@WebServlet(“资源路径”)的注解之外,还要使用@MultipartConfig表示文件上传。
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String uname = req.getParameter("uname"); // uname代表的是表单元素input的name属性值
System.out.println("姓名: " + uname);
// 文件上传
// request.getPart(name) 得到上传的文件对象,name代表的是file文件域的name属性值
Part part = req.getPart("myfile");
// 得到上传的文件的文件名
String fileName = part.getSubmittedFileName();
System.out.println(fileName);
if(fileName!=null&&!"".equals(fileName)){
// 设置得到文件的 存放的路径
String realPath = req.getServletContext().getRealPath("/upload/");
System.out.println(realPath);
part.write(realPath+fileName);
}
}
11.2 文件下载
11.2.1 超链接下载(常用)
- 浏览器遇到能够识别的资源,会直接显示;遇到不能识别的资源,则会进行下载。
- 可以通过download属性进行下载,如果未设置download属性的属性值,则下载名是文件名;
<a href="1.jpg">图片</a>
<a href="test.html">HTML</a>
<a href="Q-Dir.exe - 快捷方式.lnk">快捷方式</a>
<hr>
<a href="1.jpg" download>图片</a>
<a href="1.jpg" download="aa.png">图片</a>
<br><br><hr>
<form action="downloadServlet">
文件名:<input type="text" name="fileName"> <button>下载</button>
</form>