重定向
- 需要浏览器多次请求,服务器内部各个类之间联系比较弱(几乎没有数据传递)
- request.getRequestDispatcher("/home.jsp").forward(request, response);
- 通过请求reque获取请求转发器
- 在请求转发器中设置要转发的位置
- 调用请求转发器的forward方法进行转发,转发时把request和response传递给下一个页面(servlet或JSP)
- 转发成功时:
- 响应状态码通常是200
- 转发时浏览器不知道最终是那个页面(地址)返回了响应
- 经常表示为浏览器的地址栏不变化,或者与真实地址不同
转发
- 服务器内部联系紧密,可以发送大量数据,对于浏览器来说只有一次请求
- response.sendRedirect(request.getContextPath() + "/fail.jsp");
- 通过response的sendRedirect()方法发送一个重定向响应
- sendRedirect()方法会把状态码设置为301/302
- 还会添加Location头,Location头的值就是参数指定的重定向的地址
- 重定向成功时
- 响应状态码为301(永久地移动到其他位置)/302(临时重定向到一个位置)
- 浏览器的地址栏会变化,能看到最终是那个页面(Servlet或JSP)
附加Tomcat源代码
- 方法1
- 随便找一个Servlet类,按F3找它的定义,在弹出的页面上点击“Attach Source”按钮。在弹出的窗口选择源代码所在位置即可(通常选择external files)
- 方法2
- 在项目视图的Libranes中找到Apache Tomcat,展开,找到servlet-api.jar,右键属性java Source Attachment。选择源代码即可
接口
- 接口定义
- 在Java中,接口是一种特殊的类型。通过interface关键字定义
- 可以在接口中声明一些属性和方法
- 声明的方法可以不实现(类似于抽象方法)
- 接口实现
- 其他类可以选择实现某个接口或某一些接口
- 使用implements 接口名1,接口名2,......
- 实现接口通常意味着要实现接口规定接口的方法和属性
- 接口对于程序设计的意义
- 第一重含义(强制)
- 接口是给设计师使用的工具
- 目的规范程序代码,保证(强制)编码者实现统一的设计意图(不实现接口指定的方法或者方法签名走样就会报错)
- 第二重含义(约定)
- 接口是一个约定,方便双方或多方合作
- 可以使各方写的类能够互相调用
- 比如Tomcat是一个通用的网络程序,他只能处理网络和协议的功能。但是不懂客户的业务逻辑,此时就需要第三方开发者实现具体的业务逻辑。
- 实现后Tomcat怎么调用开发者实现的方法呢?
- 开发实现这个接口
- Tomcat调用这个接口
- 第一重含义(强制)
Servlet接口
- 是开发者和Tomcat的约定、
- 内部方法
- init()—>初始化Servlet
- getServletConfig()—>返回配置信息
- getServletinfo()—>返回描述信息
- service—>处理请求的一手方法
- destory—>销毁
- HttpServlet
- 继承自:GenericServlet
- GenericServlet实现了:Servlet
- 抽象类
- 实现了基本的HTTP协议
- 支持GET、HEAD、POST、PUT、DELETE、TRACE、OPTIONS
- GET:用来获取资源
- POST:用来新增资源
- PUT:用来修改资源
- DELETE:用来删除资源
- 基本实现了对资源的增删改查操作
- GET:请求支持if-Modified-Sence缓存检查机制
- HEAD:不会返回响应体
- TRACE:将请求头信息收集到响应体中返回
- OPTIONS:返回了所有支持的请求方法(子类实现几个doXXX就返回几个XXX)
- 其他请求默认返回Not_Allowed,所以子类实现相应方法时,不要调用super.doXXX
- service方法会检查请求报文中的请求方法 request.getMethod(),根据请求方法将请求转发给doXXX()方法处理。所以service方法只是实现简单调度作用
- GenericServlet:几乎什么没干
- 继承自:GenericServlet
- 创建Servlet类时,对话框
- Name——><servlet-name>
- Description——><description>Servlet处理什么请求,特殊注意事项
- Initialization Parameters——><init-param>传入Servlet类的参数
- URL mappings——><urlpattern>映射到Servlet类的URL。可以指定多个
- <url-pattern>的几种写法
- 精确匹配:/api/user/login:/admin/user
- 后缀名:*jsp:*action:*.do
- 路径:/admin/*:凡是/admin/开头的都匹配
- /*:所有请求
- 缺省:/:当其他匹配没有成功时,交给这个映射处理
- 应用路径
- 一个应用对用一个Dynamic Web Project
- 应用路径不是固定的
- 在开发阶段,通过Eclipse可以改变它:Content root
- 在生产环境中,由部署或配置决定
- 所以应用路径在源代码(包括jsp、Servlet)不能写死!!
- 如果在jsp中优先使用 JSTL <c:url value="/login">
- 如果在Java代码中(Servlet)中
- 使用request.getContextpath()获取
Session
- Session是一个跨页面(Servlet、JSP)的数据共享机制
- Session默认是存储在内存中的。
- 当应用分布式部署到多台服务器,首先要解决的就是Session问题
- Session通过javax.servlet.http.HttpSession实现
- 常用方法
- setAttribute(key, value):把数据存储到Session中
- getAttribute(key):获取Session的值,返回值为Object,强转后才可以方便的使用
- invalidate():让所有Session值失效
- removeAttribute(key):删除指定的Session值
- 在JSP中过去Session值
- 方法1:使用<% session.getAttribute(key) %>
- <% %>:代码块,可以把Java代码写进HTML
- session内置对象,可以在页面上直接通过session对象直接访问Session
- 方法2:使用EL表达式:${sessionScope.key}
- EL表达式是为了简化对内置对象中的数据的访问
- JSP有九大内置对象,四大作用域
- 方法1:使用<% session.getAttribute(key) %>
- 常用方法
- Sessionid
- Session.getid:可以获取Sessionid
- Sessionid是一个随机字符串(随机数)
- 每次会话使用一个Sessionid
- 在用户访问服务器的过程中,服务器会在某一次响应中通过Set-Cookie头向浏览器发送一个JSESSIONID。浏览器接到这个Cookie之后,会将之存储下来。以后每一次请求服务器时,都会通过Cookie头携带这个JSESSIONID
- 服务器通过JSESSIONID区分不同的用户
- 而且服务器端Session数据也被JSESSIONID分成不同的区域
- 通过session.setAttribute()及getAttribute()等方法操作Session数据时,都只会在当前JSESSIONID关联的区域内操作。即,每个用户只能操作自己的Session
Cookie机制
- 服务器通过Set-Cookie响应头可以向浏览器设置Cookie
- 浏览器会将收到的Cookie保存下来
- 以后每次请求时都会通过Cookie请求头将Cookie发送给服务器
- Cookie可以设置保存时间(这个时间可以是绝对时间,也可以时在浏览器关闭时清除)
- Cookie可以设置域名(在本域名有效,在其它域名中无法获取----Cookie不跨域)
- Cookie可以设置路径(在本路径有效,在其他路径中无法获取)
- Cookie可以区分协议(可以设置Cookie只在https的协议中能获取)
如果浏览器不支持Cookie,或者程序员不选择通过Cookie保存JSESSIONID时,可以通过URL夹带JSESSIONID
Filter
- Filter作用
- Filter可以在请求处理之前以及请求处理之后对请求或响应进行限制、加工或转换
- 比如:登录保护、保存日志、转换编码、业务统计、响应格式转换等。。。
- Filter是一个接口
- init:初始化
- doFilter:执行过滤
- destory:销毁
- Filter和Servlet组成了一个链条chain
- 多个Filter时,谁的<filter-Mapping>在web.xml中,代码靠前谁先执行
- 如果使用注解的话,按照名字的字母排序
- 通过Filter实现登录保护(用户身份验证)
- 登录叫身份认证
- 与权限有关的叫用户授权
- 步骤
- 创建过滤器
- 在过滤器的前处理部分,检查session中是否有用户数据
- 没有则未登录
- 重定向到登录页
- return,停止所有后续处理
- 有则说明登录
- 调用chain.doFilter继续处理
- 没有则未登录
- 退出
- 创建LogoutServlet
- 在doGet方法中
- 清除session数据
- 重定向登录页
- 在doGet方法中
- 创建LogoutServlet