Servlet细节&Cookie&Session

Servlet细节&Cookie&Session


Servlet的细节问题


  • 一个Servlet可以有多个映射<url-pattern>
<servlet>
  <servlet-name>MappingServlet</servlet-name>
  <servlet-class>com.ghyz.mapping.MappingServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>MappingServlet</servlet-name>
  <url-pattern>/mapping</url-pattern>
  <url-pattern>/mapping2</url-pattern>
  <url-pattern>/mapping3</url-pattern>
</servlet-mapping>
  • Servlet<url-pattern>可以使用通配符*进行配置
    • /*表示可以使用任意字符访问当前的Servlet
    • /system/*可以使用以/system为前缀,后面是任意字符即可访问当前的Servlet
    • *.xxx任何字符,加上指定的后缀名即可访问当前的Servlet
  • Servlet<servlet-name>不能为default如果为default那么当前项目中的静态资源将无法被访问
    • 因为在Tomcat中有一个默认的Servlet配置其<servlet-name>就是default专门用来访问项目中的静态资源。
  • Servlet中初始化操作非常复杂的时候,那么这种操作就非常好使,给第一个访问用户的体验就很差
    • 问题的根本:初始化操作放在了第一次访问的时候执行
    • 解决方案:应该将耗时的初始化操作放在第一次访问执行之前
<servlet>
  <servlet-name>MappingServlet</servlet-name>
  <servlet-class>com.ghyz.mapping.MappingServlet</servlet-class>
  <!-- 设置Servlet在Tomcat中启动的时候执行初始化,数字越小越先执行 -->
  <load-on-startup>0</load-on-startup>
</servlet>

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找到刚才开辟的空间

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,235评论 11 349
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,649评论 18 139
  • 一.Servlet细节 1.Servlet细节 1):一个Servlet向外暴露多个资源名称(一般来说,一个Ser...
    贾里阅读 351评论 0 0
  • 精挑细选河边叶,风起微波。芦影婆娑,洗尽灰尘待糯合。 多加香料轻折叶,捆绑防脱。加水装锅,煮沸出盘急烫舌。 ——柳公子
    良柳如烟阅读 274评论 3 4
  • 心还没有安定下来,生活怎么安定?人们总是说,到了年纪了,你该去结婚生子了。年龄成了标准。可是,我没有定下心来,没有...
    我是狐狸一只阅读 291评论 1 0