Servlet细节&Cookie&Session

Servlet细节&Cookie&Session


Servlet的细节问题


  • 一个Servlet可以有多个映射

  MappingServlet
  com.ghyz.mapping.MappingServlet


  MappingServlet
  /mapping
  /mapping2
  /mapping3

  • Servlet可以使用通配符*进行配置
    • /*表示可以使用任意字符访问当前的Servlet
    • /system/*可以使用以/system为前缀,后面是任意字符即可访问当前的Servlet
    • *.xxx任何字符,加上指定的后缀名即可访问当前的Servlet
  • Servlet不能为default如果为default那么当前项目中的静态资源将无法被访问
    • 因为在Tomcat中有一个默认的Servlet配置其就是default专门用来访问项目中的静态资源。
  • Servlet中初始化操作非常复杂的时候,那么这种操作就非常好使,给第一个访问用户的体验就很差
    • 问题的根本:初始化操作放在了第一次访问的时候执行
    • 解决方案:应该将耗时的初始化操作放在第一次访问执行之前

  MappingServlet
  com.ghyz.mapping.MappingServlet
  
  0

Servlet3.0的新特性--注解配置


Servlet3.0开始Servlet就支持使用注解进行配置,可以使用注解来替代部分web.xml文件

  • 使用注解的准备工作(web.xml的配置)
    • metadata-complete="true":指定服务器忽略Servlet上面的注解
    • metadata-complete="false":指定服务器编译Servlet上的注解(缺省值)
  • 选择注解还是web.xml配置Servlet?
    • web.xml维护难度大
    • 注解:将硬编码拉回到程序中,不好维护
    • 如果当前配置是针对某一个Servlet的话,可以使用注解
    • 如果是通用的配置,应该使用web.xml例如给多个Servlet共享数据

使用注解配置Servlet示例代码

@WebServlet(value="/anno", 
loadOnStartup=0, 
initParams={@WebInitParam(name="encoding", value="UTF-8")})
public class AnnoServlet extends HttpServlet {
  // TODO...
}

Servlet线程安全问题


  • Servlet在整个应用中只有一个实例

问题的根本原因:因为有多个线程并发访问(修改)当前的Servlet中的资源,又因为Servlet是单例的,所以所有的成员,都会去访问同一个对象

  • 解决方法
    • 可以让当前的Servlet去实现一个接口SingleThreadModel,表示当前的Servlet只能被同一个线程访问该方法不推荐,已经被淘汰了
    • Servlet中使用局部变量代替成员变量

Http协议无状态带来的问题


HTTP是无状态协议,也就是没有记忆力,每个请求之间无法共享数据。这样就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。

web中的回话:在浏览器打开的时候,在这之钱应该要进行多次一问一答的交互,关闭浏览器的时候结束

  • 解决方案:解决HTTP无协议状态的问题
    • 使用参数传递机制
    • cookie
    • session

在请求路径后面跟上响应参数如/param/list?username=ghyz这种方式可以解决数据共享的问题,但是,参数显示在了地址栏中,不安全(不推荐)

Cookie


Cookie客户端技术,将共享数据保存在客户端中(浏览器)

  • 原理

浏览器记住键值对,是向响应头中添加一下头即可set-Cookie:name=tom
浏览器记住之后,向服务器发送键值对,是在请求头中添加下面的信息Cookie:name=tom

  • Cookie的细节
// 1.创建Cookie对象,并设置共享数据
Cookie c = new Cookie(String name, String value);
// 2.将Cookie响应给浏览器
response.addCookie(c);
// 3.获取Cookie中的共享数据
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
  if ("username".equals(c.getName())) {
    String value = c.getValue();
  }
}
// 4.修改Cookie中的共享数据
// 方式一:获取到要修改的Cookie对象,调用setValue(String newValue);
// 方式二:重新创建一个名字和要修改的Cookie一样的Cookie对象即可,修改之后需要将Cookie重新发送给浏览器
// 5.Cookie的生命周期(默认是在关闭浏览器就销毁)
void setMaxAge(int expiry)
// expiry > 0:设置生存的时间为expiry妙
// expiry = 0:立即删除当前的Cookie
// expiry < 0:缺省值,在关闭浏览器就销毁
// 6.删除Cookie
  c.setMaxAge(0);
// 7.Cookie中的name和value不支持中文
// 解决方案
// 将文中的字符先重新编码(编码成非中文的)
// 编码
URLEncoder.encode("大黄", "UTF-8");
// 解码
URLDecoder.decode("对应的编码","UTF-8");

// 8.cookie的路径和cookie的域范围
// 在Servlet中创建的Cookie对象,会默认的将Servlet的相对路径设置给Cookie
// 如:/cookie/login-->相对路径/cookie/
// 此时访问/session/list的时候,浏览器不会将Cookie中的数据发送给服务器
// 解决方案
// 通常可以将Cookie的路径设置为/,表示访问当前项目中的所有资源,都会将共享数据发送给服务器
c.setPath("/");

// 域范围
// 如果使用的二级域名。可以使用下面的方式进行共享
// void setDomain(String path)
c.setPath("/");
c.setDomain("baidu.com");

// Cookie的缺陷
// 1.取值的时候,操作复杂
// 2.不支持中文,中文参数很多的时候,操作很麻烦
// 3.cookie一次只能保存一个字符串,如果一次需要保存多个共享数据,就需要创建多个Cookie对象
// 4.将共享数据保存在浏览器中不安全
// 5.Cookie在浏览器中有数量大小的限制,在低版本的IE中
// 每个应用在浏览其中只能保存20个Cookie信息,其他的可以保存50个

Session


  • 什么是session

服务器端的会话技术,将共享数据保存到服务端,同时在可断保存一个id,以后就根据id查找到服务器端的共享数据

session实际就是一个会话cookie

  • 使用方法
// 1.如何获得Session
HttpSession session = request.getSession();
// 2.如何操作
session.setAttribute(key, value);
session.getAttribute(key);
session.removeAttribute(key);
session.getAttributeNames();
  • 原理

浏览器第一次访问服务器,服务器会在内存中开辟一个空间(session)

session对应的id发送给浏览器

那么下次浏览器再去访问服务器,会把sessionId交给服务器,服务器通过sessionId找到刚才开辟的空间

你可能感兴趣的:(Servlet细节&Cookie&Session)