Servlet学习笔记
Java Web Application简介?
-
Java Web Application 是由一组 servelt、HTML、类 、以及其他可以被绑定的资源构成,她可以在实现了servlet规范的servlet容器中运行。
-
Java Web应用中包含:
- 动态资源:在服务端具有处理能力的资源。
- 程序根据不同用户给同一个请求反馈不同的响应内容
- 常见的动态资源:各种类、JSP、SERVLET等
- 静态资源:在服务器上没有处理能力的资源。
- 程序无差别的响应,同一个请求的响应内容相同
- 常见的静态资源:静态文本、HTML、CSS、JavaScript、图片等
- web.xml文件:用于描述整个web应用程序的信息
- 动态资源:在服务端具有处理能力的资源。
Web Application 的结构
什么是servlet?
Servlet是运行在服务器上的java类,它可以接收客户端的请求,并向客户端做出响应。
Web Application 执行过程
servlet容器:为Java Web应用提供运行时环境,并且负责管理servlet/jsp的生命周期以及其他的一些共享数据
Tomcat
tomcat目录结构
bin ——可执行文件,存放用于启动或者停止Tomcat服务的脚本文件
conf ——存放tomcat服务器的配置文件
lib ——存放tomcat运行所需的依赖包
logs ——存放日志文件
temp ——存放临时文件
webapps ——项目发布目录
work ——存放由jsp生成的servlet文件
servlet生命周期
创建、初始化、执行业务、销毁
1、客户端发送请求
2、如果请求是个servlet,那么tomcat会直接到
servlets容器中去查找是否有所请求的servlet实例
3、如果有servlet3实例,那么就直接调用这个实例
进行处理,然后返回结果给客户端。
4,去找到所请求资源对应的class文件,并加载到jVM中
S、servlet容器会去调用这个serlvet的构造方法。
6、创建好servlet的实例后,servlet容器会调用这个实例的init方法,用于初始化servlet(执行完init方法,表示这个servlet:实例已经准备好了,可以调用了)
7、servlets容器会调用servlet的service方法。
8、默认的service方法,会根据客户端请求的方法不同
(get/POST)来调用响应的doGet/doPost方法
9、响应消息到客户端
请求响应对象
请求对象:所有从客户端发送到服务端的内容都在请求对象中;(如:请求的资源,向服务器发送的表单内容,cookies 对象)
响应对象:从服务端向客户端响应的内容都在响应对象中;(如:向客户端响应一个HTML页面;发送一段文字;写cookie)
Get 和 Post 的区别
HTTP请求的方法:
HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和CONNECT 方法
但其实我们大部分情况下只用到了GET和POST。原因如下:
- 很多人贪方便,更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点。
- 对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。我们在更新资源的时候,都是我们所写的程序来完成的,只需要获取到表单数据就可以了进行了。与具体的提交方式关系并不大。
- 早期的Neb MVC框架设计者们并没有有意识地将UL当作抽象的资源来看待和设计,所以导致一个比较严重的问题是传统的Web MVC框架基本上都只支持GET和POST两种HTTP方法,而不支持PUT和DELETE方法。
Get: 用于信息获取(查询操作),而且是安全的和幂等的
- 安全:指操作用于获取信息,而非修改信息。Get请求一般不产生副作用,它仅仅是获取资源信息,不会修改、增加数据,不会影响资源的状态
- 幂等意味着对同一URL的多个请求应该返回同样的结果
Post: 表示可能修改服务器上的资源的请求
表现上的区别:
- GET后退刷新,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)
- Get请求表单数据是放在url参数中的;而post请求,表单内容是放在请求体中的
- GET书签可收藏,POST书签不可收藏
- GET能被缓存,POST不能缓存
- GET编码类型 application/x-www-form-url,POST 编码类型encodedapplication/x-www-form-urlencoded 或 multipart/form-data,为二进制数据使用多重编码
- GET历史参数保留在浏览器历史中,POST参数不会保存在浏览器历史中
- GET对数据长度有限制,当发送数据时,GET方法向URL添加数据,URL的最大长度是2048个字符。POST无限制
- GET 只允许ASCLL字符,POST没有限制,也允许二进制数据、
- 与POST相比,GET的安全性较差,因为所发送的数据是URL的一部分。在发送密码或其他敏感信息时不能使用GET
- POST比GET更安全,因为参数不会保存在浏览器历史或web服务器日志中,GET的数据在URL中对所有人都是可见的,POST的数据不会显示在URL中
Get、Post的选择
若符合下列任一情况,则用POST方法(如果要修改服务上的数据,那么选择POST):
- 请求的结果有持续性的副作用,例如,数据库内添加新的数据行。
- 需要提交的数据量比较大时。
- 要传送的数据不是采用7位的ASC1编码,例如二进制数据等。
若符合下列任一情况,则用GET方法(查询服务器上的数据选择GET):
- 请求是为了查找资源,HTML表单数据仅用来帮助搜索。
- 请求结果无持续性的副作用。
- 收集的数据及HTML表单内的输入字段名称的总长不超过2048个字符。
中文乱码问题的解决
解决HTML文档解析问题:
需求:在响应到客户的的信息中,
本来是需要按照html的标签来解析换行的,但是直接以文本的形式直接显示了出来。
说明出现这个问题的原因:各个浏览器对一个文档的默认解析方式是不同的。有的浏览器默认是以文本形式进行解析;有的浏览器是以html文本的形式进行解析。
如何解决:在向客户端发送响应消息的时候,指定内容格式。
设置响应内容格式:
//设置响应内容的类型,将其设置为“text/html”之后
//浏览器就会以html文档的形式进行解析.
response.setContentType("text/html");
解决POST方式的中文乱码问题:
问题出现的原因:页面提交的时候,和servlet进行获取的时候的编码格式不统一造成的。tomcat默认的编码格式:IS0-8859-1,而这种编码方式是不支持中文的。所以会出现中文乱码。
解决方案:在接收和响应的时候设置固定的编码格式为utf-8
示例代码:
//解决post方式的中文乱码问题,
//1、设置请求对象的编码格式为utf-8.:
//为了保证,在servlet中获取到的字符不会有乱码.
request.setCharacterEncoding("utf-8");.
//设置响应对象的编码格式为utf-8.
/为了保证,servlet向客户端响应的消息不会有乱码
response.setCharacterEncoding("utf-8");.
解决GET方式的中文乱码问题:
1、第一种解决方式:
- 读取用户名和密码。
- String name request.getParameter(“name”);
- 对请求数据进行字符编码(重新对获取到的字符串进行编码)
- name new String(name.getBytes(“ISO-8859-1”),“UTF-8”);.
2、设置server.xml文件
在Tomcat目录结构conf\server.xml中设置字符集
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
请求转发和重定向
请求转发和重定向的区别?
forward(转发):
是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程实在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址
redirect(重定向):
是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的URL
- 转发是服务器行为,重定向是客户端行为
- 从地址栏来看转发是服务器请求资源,服务器直接访问目标地址的URL,将响应内容发给服务器,客户端不知道发送的内容从哪来的,转发只能看见第一次访问的页面URL,以后的工作都是有服务器来做的,地址栏不变;重定向是服务端重新请求地址,地址栏显示的是新的URL
- 转发页面和转发到的页面可以共享request数据;重定向不能共享数据
- 重定向跳转后必须加上return,要不然页面虽然跳转了,但是还会执行跳转后面的语句;转发是执行了跳转页面,下面的代码就不会在执行了
- 绝对路径中的"/":转发是项目的根目录,只能转发到当前项目的其他资源;重定向是服务器根目录,可以重定向到任意互联网资源
- 转发效率高,重定向效率低
Cookie和Session
Cookie
创建Cookie
//创建cookie
//cookie中不允许特殊字符,例如空格,?
//在写cookie的时候,cookie的值,一般会进行url编码操作
Cookie cookie = new Cookie("username",URLEncoder.encode(username,"utf-8"));
//设置用户名在cookie中保存1个月
//单位(秒)
cookie.setMaxAge(30*24*60*60);
//将cookie写到浏览器中
response.addCookie(cookie);
获取Cookie
//获取cookie
Cookie[] cookies = request.getCookies();
//遍历cookie数组,获取指定的cookie
for(Cookie cookie:cookies){
System.out.println(cookie.getName()+"="+URLDecoder.decode(cookie.getValue(),"utf-8"));
System.out.println(value);
}
删除Cookie
//删除cookie
//将cookie的过期时间设置为当前时间之前,对应到servlet程序
//参数小于0
Cookie.setMaxAge(-1);
Cookie 使用示意图
Cookie的重要属性
- setMaxAge(count):count表示最长有效时间,单位秒;count<0,表示删除;count==0,表示cookie有效时间为整个会话期间(会话结束失效)
- cookie.setDomain(“”):设置cookie的有效域名。一般不设置,默认当前域名。
- cookie.setPath(“/”):设置cookie的有效路径。"/"表示根目录,表示当前域名下的所有资源都有效
Session
Session(会话)是在一段时间内,一个客户端与服务器的一连串相关的交互过程
Session的原理
1.session存放在服务器上。并且会为每一个用户都创建一个sessioni对象
2.在服务器上每一个session都会有一个唯一的编号-sessionId
3.在客户端的cookie中会存放一个JSESSIONID,
当客户端访问服务器的时候,会带着这个sessionI少到服务器,
然后根据这个id找到自己的session
getSession方法:
- getSession(boolean);
- true:去request中获取Session,如果Session不存在则创建一个新的Session并返回;如果Session存在,则返回已存在的Session
- false:获取Session,如果Session 不存在,那么返回null,
- 无参数:getSession() <=> getSession(true)
//POST方法
//1.获取登录信息
String username = reg.getParameter("username");
String userpwd = reg.getParameter("userpwd");
//2.判断
if(username.equals("admin")&& userpwd.equals("123")){
//3.写Session
//3.1获取session对象
HttpSession session = reg.getSession();
reqp.getWriter().println("sessionid="+session.getId());
//3.2向session的attribute中添加数据
//session.setAttribute("username",username);
//session.setAttribute("userpwd",userpwd);
//可以向session中存入对象
User user = new User();
user.setUsername(username);
user.setUserpwd(userpwd);
session.setAttribute("user",user);
//4.使用get方式请求此serblet,或则输出一段登陆成功的信息
resp.getWriter().println("登录成功,<a href='"+req.getContextPath()+"/loginsession'>点击查询用户信息</a>");
}else{
}
//GET方法
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
//1.获取session对象
HttpSession session = req.getSession();
if(session.getAttribute("user")!=null){
//2.读取session
resp.getWriter().println(session.getAttribute("user"));
}else{
resp.getWriter().println("<h2>还没有登录</h2>")
}
设置session 过期时间
session 过期时间:从最后一次访问session开始计时,如果在过期时间内没有对session进行再次访问,那么系统将会收回session对象
方法1:在程序中设置(不常用)
//方法1:在程序中设置(不常用)
//设置session 过期时间(单位:秒)
session.setMaxInactiveInterval(6000);
方法2:在项目的web.xml中进行设置
<!--方法2:在项目的web.xml中进行设置-->
<session-config>
<!--设置sesion的过期时间,单位(分钟)-->
<session-timeout>20</session-timeout>
</session-config>
方法3:在tomcat的web.xml中进行设置(与方法2相同)
<!--方法3:在tomcat的web.xml中进行设置-->
<session-config>
<!--设置sesion的过期时间,单位(分钟)-->
<session-timeout>20</session-timeout>
</session-config>
-
在tomcat中设置,一般称为session的默认过期时间(一般都是30分钟),它对所有发布到这个服务器的项目起作用
-
在项目的web.xml中设置,只会对本项目起作用,优先级高于tomcat中的设置
-
在程序中设置,一般是在临时需要增加session 过期时间的时候进行设置
application/servletContext
servletContext是什么?
WEB容器启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,代表当前Web应用,又称为Servlet上下文环境
ServletContext对象的获取:
- Servlet对象维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过 ServletConfig.getServletContext()方法获取ServletContext()对象
- 直接在servlet中调用getServletContext()方法直接获取ServletContext()对象
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。
ServletContext对象通常也称为context对象/application对象
application特点
- 存放在服务器端
- 所有用户公用
- key-value形式存放
- 可以存放任何对象
ServletContext application = req.getServletContext();
application.setAttribute("appname","我的servlet程序");
application.getAttribute("appname");
application.getInitParameter("");
Cookie、Session、Application区别
Cookie | Session | Application | |
---|---|---|---|
保存位置 | 客户端 | 服务端,客户端保存sessionid | 服务端 |
数据权限 | 用户独有 | 用户独有 | 共有 |
数据类型 | 字符串 | object | object |
保存时间 | 长期(可设置) | 会话结束后销毁/过期 | 服务启动到服务关闭 |
应用场景 | 不重要的信息 | 重要的信息 | 需要共享的信息 |
过滤器
什么是过滤器?
Filtering基本思想:
将jsp,servlet,html看作资源,容器用来处理这些资源,并为资源提供服务。因此,可以在处理这些资源之前或之后,通过过滤器增加一些通用功能;比如:登录权限验证、字符编码转换、资源访问权限控制、敏感词过滤。并且这些过滤器可以形成一个链。
- 过滤器本身是一个类,必须要实现Filter接口
- 在doFilter方法的最后一句,必须要有chain.doFilter(request,response);
- 初始化参数不要在程序中写死,应该放在配置文件中
监听器
什么是监听器?
概念:
web监听器是一种servlet中的特殊的类,它能帮助开发者监听web中的特定事件,比如ServletContext,HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控。是观察者模式的
一般应用监听器的常用用途
- 统计在线人数,利用HttpSessionLisener
- 加载初始化信息:利用ServletContextListener
- 统计网站访问量
- 实现访问监控(监听request对象)