所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

Java JSP九大内置对象详解|中篇核心知识与面试考点实战教程

Java JSP九大内置对象详解|中篇核心知识与面试考点实战教程 一

文章目录CloseOpen

request与response:Web交互的核心信使

在JSP里,用户的每一次操作——不管是点击按钮提交表单,还是在地址栏输入URL——本质上都是一次“请求-响应”的过程。而request和response这两个对象,就是服务器和客户端之间传递信息的“信使”。你写JSP页面时可能经常见到这样的代码,但你真的懂它背后的逻辑吗?

request:客户端数据的“搬运工”

request对象就像快递员,专门负责把客户端(浏览器)提交的数据送到服务器。用户在表单里填的用户名密码、URL里跟的参数(比如?id=123)、甚至浏览器的类型信息,都被它打包带过来。我见过很多新手只会用getParameter(String name),但其实它还有很多实用方法。比如你要获取一个复选框的多个值,就得用getParameterValues("hobby"),返回的是String数组;如果想一次性拿到所有参数,getParameterMap()会返回一个Map集合,遍历起来特别方便。

不过这里有个坑你一定要注意:请求参数的编码问题。去年我帮一个朋友调bug,他的JSP页面提交中文表单,后台拿到的总是乱码。检查代码发现,他在JSP里设置了,但没在Java代码里处理request编码。后来我让他在获取参数前加上request.setCharacterEncoding("UTF-8"),问题瞬间解决。记住,这个方法必须在getParameter之前调用,不然没用——就像快递员已经把包裹拆开了,你再告诉它“请用中文标注”,当然来不及。

Oracle的JSP官方文档里明确提到,request对象的生命周期和一次HTTP请求绑定,请求处理完它就会被销毁(参考链接{:target=”_blank” rel=”nofollow”})。所以你千万别想着在一个请求里存的数据,能在下一个请求里拿到——比如你在A.jsp里用request.setAttribute("user", "张三"),跳转到B.jsp后想request.getAttribute("user")获取,结果肯定是null。这时候要么用转发(request.getRequestDispatcher("B.jsp").forward(request, response)),要么把数据存到session里,这点面试经常考,记牢了。

response:服务器指令的“传声筒”

如果说request是“收件员”,那response就是“发件员”,负责把服务器处理后的结果告诉客户端。最常用的场景有两个:一是向页面输出内容,比如response.getWriter().print("登录成功");二是页面跳转,比如登录失败后跳回登录页,用response.sendRedirect("login.jsp")。但这里有个细节你可能没注意:response.getWriter()和JSP自带的out对象有啥区别?

其实out是JSP的内置输出对象,它有自己的缓冲区,数据会先存在里面,等页面处理完再一起发给客户端;而response.getWriter()是直接往响应流里写数据,不经过JSP缓冲区。我之前就踩过坑:在JSP里先写了out.print("Hello"),又用response.getWriter().print("World"),结果页面显示“WorldHello”,顺序完全反了。后来查资料才知道,因为response.getWriter()的数据先到响应流,而out的缓冲区后刷新,所以 你在一个页面里统一用一种输出方式,别混着用。

还有个高频面试题:转发(forward)和重定向(redirect)的区别。简单说,转发是服务器内部的“悄悄话”,浏览器地址栏不会变(比如从A.jsp转发到B.jsp,地址栏还是A.jsp),而且request对象里的数据能传递过去;重定向则是服务器告诉浏览器“你去访问新地址吧”,浏览器会发一个新的请求,地址栏会变成新URL,这时候request里的数据就丢了。举个例子:用户登录成功后,你想跳转到首页并显示用户名,这时候要用转发,因为需要把用户信息通过request传到首页;而如果登录失败,让用户重新登录,就用重定向,反正不需要保留之前的错误信息。

session与application:状态管理的两把钥匙

HTTP协议是“无状态”的,意思是服务器记不住你是谁——你第一次访问和第二次访问,对它来说都是陌生的。那怎么实现“登录后保持状态”“记住购物车商品”这样的功能?这就需要session和application这两个“状态管理工具”了,不过它们的“管理范围”可不一样。

session:用户专属的“储物柜”

session对象相当于给每个用户分配了一个专属的“储物柜”,里面可以存用户的登录信息、购物车数据等。只要用户没关闭浏览器,或者没超过服务器设置的超时时间(默认30分钟),这个“柜子”就一直有效。你可以用session.setAttribute("user", userObj)存数据,用session.getAttribute("user")取数据,不用的时候session.invalidate()销毁它(比如用户点击“退出登录”)。

但这里有个容易踩的坑:session的“有效期”问题。我之前做一个在线考试系统,用户抱怨“明明没退出,考试做到一半突然提示重新登录”。排查发现是服务器默认的session超时时间设成了10分钟,而考试需要30分钟。后来在web.xml里加上30,问题就解决了。如果你不想改全局配置,也可以在代码里用session.setMaxInactiveInterval(1800)(单位秒)单独设置某个session的超时时间。

还有个面试常考的点:session是怎么识别用户的? 其实服务器会给每个session生成一个唯一的ID(JSESSIONID),第一次创建session时,服务器会通过response把这个ID存到客户端的cookie里。之后用户每次请求,浏览器都会带着这个cookie,服务器根据JSESSIONID找到对应的session。所以如果用户禁用了cookie,session还能用吗?答案是可以,不过需要用URL重写(response.encodeURL("index.jsp")),让JSESSIONID跟在URL后面(比如index.jsp;jsessionid=xxx),但这种方式不太安全,一般 还是让用户开启cookie。

application:全局共享的“公告栏”

如果说session是“个人储物柜”,那application就是整个网站的“公告栏”——所有用户都能看到上面的内容,而且只要服务器不重启,内容就一直在。比如网站的在线人数统计、全局配置参数(如数据库连接信息),都适合存在application里。用法和session类似,application.setAttribute("onlineCount", 100)存数据,application.getAttribute("onlineCount")取数据。

但千万别把它当成“万能存储箱”!我刚工作时接手过一个项目,前同事图省事,把所有用户的信息都存在application里,结果用户A登录后,用户B打开页面看到的竟然是A的信息。这就是没搞懂作用域——application是所有用户共享的,你存个用户信息进去,后面的用户一覆盖,前面的就没了。所以记住:用户专属数据用session,全局公共数据用application,比如网站的logo路径、客服电话这种所有人都一样的内容。

为了让你更直观地区分,我整理了一个作用域对比表,平时开发或面试前都可以看看:

对象类型 作用范围 生命周期 典型用途
request 单次请求内 从请求开始到响应结束 表单数据传递、URL参数获取
session 单个用户会话 用户登录到退出/超时 用户登录状态、购物车
application 整个Web应用 服务器启动到关闭 在线人数统计、全局配置

你可以试着把这四个对象的用法 成思维导图,或者在项目里刻意练习——比如用request处理一次表单提交,用session实现用户登录,再用application做个简单的网站计数器。刚开始可能会忘,但练得多了就会形成肌肉记忆。

对了,如果你在实际开发中遇到“对象作用域搞不清”“参数获取不到”这类问题,欢迎在评论区告诉我具体场景,我可以帮你分析分析。毕竟这些坑我当年都踩过,说不定能给你省不少时间呢!


要说request、session、application这三个对象的作用域区别,其实就像你在不同场合放东西的“储物柜”,有的只能用一次,有的专属你用,有的大家共用。先看request,它就像超市里的临时寄存柜,你存了东西,取出来用完这一趟就失效了——对应到Web里,就是从你在浏览器点下提交按钮,到服务器处理完请求、把页面返回给你,这整个“请求-响应”过程就是request的生命周期。你填表单时输的用户名密码、URL里跟的?id=123这种参数,都是靠它临时搬运,一旦页面刷新完,这些数据就自动清掉了,下次再请求就得重新传。我之前帮同事看代码,他想在两个页面之间用request传数据,结果用了重定向,数据全丢了,后来才反应过来:request只能在一次请求里用,重定向是新请求,自然拿不到。

再说说session,这就像你去咖啡馆办的会员储值卡,从你扫码登录(建立会话)到你结账离开、或者久坐没消费超时(默认30分钟,不同服务器可能设置不一样),这张卡对应的余额(你的登录状态、购物车商品)就只有你能用,别人拿不到。比如你登录电商网站后,不管跳转到商品页、购物车还是个人中心,右上角都显示你的用户名,这就是session在背后“记住”了你。我之前做项目时遇到过用户投诉“购物车商品突然不见了”,一查服务器配置,session超时设成了15分钟,用户逛久了没下单就超时失效了,后来改成60分钟,投诉就少多了——所以记着,session的超时时间可以根据业务需求调,别太死板用默认值。

application就不一样了,它像小区里的公告栏,从物业开张(服务器启动)到倒闭(服务器关闭),上面的通知(比如“小区停水通知”“当前住户120户”)所有业主(用户)都能看,而且一直都在。你在网站底部看到的“当前在线356人”,这个数字就是存在application里的,每个用户登录时让数字+1,退出时-1,不管哪个用户打开页面,看到的都是同一个实时数字。我还见过有人把数据库连接信息存在application里,省得每个页面都写一遍连接字符串,改起来也方便,改一次全网站生效——这就是公共数据该有的用法,不用重复造轮子。

其实记住一个简单的判断标准就行:如果数据只用一次,用完就扔,选request;如果数据是某个用户专属,别人不能碰,选session;如果数据是所有用户共用,而且要长期存在,选application。之前带实习生时,他把用户头像路径存到了request里,结果页面一刷新头像就没了,后来换成session才解决——这种小坑,你多踩两次就记住了。


request、session、application的作用域有什么区别?

三者的核心区别在于作用范围和生命周期:request作用于单次HTTP请求,从请求发起至响应结束后销毁,适合传递表单数据、URL参数等临时数据;session作用于单个用户会话,从用户登录至退出或超时(默认30分钟)后销毁,用于存储用户登录状态、购物车等专属数据;application作用于整个Web应用,从服务器启动至关闭期间全局共享,适合存储在线人数、全局配置等公共数据。

为什么用request获取中文参数会乱码?如何解决?

中文乱码通常是因为请求参数的编码与服务器解码不一致。JSP页面虽通过设置了页面编码,但request默认使用ISO-8859-1解码参数,导致中文乱码。解决方法:在调用getParameter()前,通过request.setCharacterEncoding(“UTF-8”)设置请求编码(需在获取参数前调用);若为GET请求(参数在URL中),还需在服务器配置中设置URL编码(如Tomcat的server.xml中添加URIEncoding=”UTF-8″)。

转发(forward)和重定向(redirect)有什么区别?分别在什么场景下使用?

转发(forward)是服务器内部跳转,浏览器地址栏不变,request对象中的数据可传递给目标页面,适合需要保留请求数据的场景(如表单提交成功后跳转至详情页);重定向(redirect)是服务器通知浏览器重新发起新请求,地址栏变为新URL,原request数据会丢失,适合不需要保留数据的场景(如登录失败后跳转回登录页)。简单说:转发是“服务器内部指路”,重定向是“告诉浏览器换条路走”。

session是如何识别不同用户的?如何设置session的超时时间?

session通过“JSESSIONID”识别用户:服务器创建session时生成唯一JSESSIONID,通过response存入客户端cookie;后续请求中,浏览器会携带该cookie,服务器据此找到对应session。若用户禁用cookie,可通过URL重写(response.encodeURL(“页面路径”))将JSESSIONID拼接到URL后。设置超时时间有两种方式:在web.xml中通过30配置全局超时(单位分钟);或在代码中用session.setMaxInactiveInterval(1800)设置单个session超时(单位秒,1800秒=30分钟)。

application对象适合存储哪些数据?使用时需要注意什么?

application对象适合存储全局共享的公共数据,如网站在线人数、全局配置参数(如数据库连接URL)、公共资源路径等。使用时需注意:application是所有用户共享的,禁止存储用户专属数据(如用户个人信息),否则会被其他用户覆盖;由于生命周期与服务器一致,存储数据不宜过大,避免占用过多内存;多线程环境下需注意线程安全,对共享数据操作时 加锁(如synchronized)。

原文链接:https://www.mayiym.com/45536.html,转载请注明出处。
0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码