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

JSP页面静态包含与动态包含使用方法|区别详解|实战教程

JSP页面静态包含与动态包含使用方法|区别详解|实战教程 一

文章目录CloseOpen

先搞懂:JSP静态包含和动态包含的核心差异

要想用对,得先明白两者的底层逻辑——这俩虽然都叫“包含”,但本质完全不一样,我用“抄作业”打个比方你就懂了:

静态包含()就像提前把别人的作业抄进自己本子里——主页面编译的时候,会直接把被包含页面的代码“复制粘贴”过来,合并成一个Servlet文件。比如你把导航栏写在header.jsp里,用静态包含的话,所有引用header.jsp的页面,都会在编译时把header的代码直接嵌进去,相当于整个页面是“一块代码”。

动态包含()则是考试的时候翻别人的作业本抄答案——主页面编译的时候不管被包含页面,等运行时(也就是用户打开页面的时候),才会单独去编译被包含页面,把它的输出结果“贴”进主页面里。就像你写作文时,临时引用同桌的一句话,这句话是同桌单独写的,跟你的作文不是“同一份草稿”。

编译时机:一个是“提前合并”,一个是“实时调用”

去年小王的问题就出在这儿——他把不变的导航栏用了动态包含,结果每次用户打开页面,服务器都要重新编译一次导航栏的代码,能不慢吗?静态包含是“一劳永逸”:编译主页面时合并被包含页面,之后不管多少用户访问,都是用已经编译好的Servlet,速度快得很;动态包含是“每次都要重新来”:用户每打开一次页面,服务器都要重新调用被包含页面的逻辑,要是被包含页面里有数据库查询,那速度肯定慢。

Oracle官方文档里也明确说了(链接:JSP Include Directive vs. Action):“include指令是编译时的合并,而include动作是运行时的包含”——这是两者最核心的区别,记牢这句话,能避开80%的坑。

变量与参数:能不能共享,差别大了

再说说变量和参数的问题,这也是很多人踩坑的点:

  • 静态包含:因为是“复制粘贴”代码,主页面和被包含页面的变量是共享的——比如主页面定义了一个String name = "张三",被包含页面也用name变量,编译时就会报错“变量重复定义”。我之前帮一个电商项目调bug,就是因为静态包含的两个页面都定义了productId,结果编译直接红了,把其中一个变量名改成itemId才解决。
  • 动态包含:被包含页面是“独立编译”的,相当于一个单独的小程序,所以主页面的变量它根本看不到。但动态包含有个好处——能传参数!比如你想给被包含页面传个用户ID,可以写,然后在userInfo.jsp里用${param.userId}就能拿到这个参数。之前做论坛项目,我用这招传用户ID到侧边栏,实时显示用户的积分和等级,特别方便。
  • 我把两者的核心差异整理成了表格,你一看就明白:

    对比项 静态包含() 动态包含()
    编译时机 主页面编译时合并代码 运行时调用输出结果
    参数传递 不能传参数,会报错 可用
    变量共享 共享变量,易冲突 变量独立,不共享
    适用场景 不变的公共内容(导航、Footer) 实时更新的内容(广告、用户信息)
    性能 编译一次,加载快 每次调用,略慢但灵活

    实操避坑:什么时候用静态?什么时候用动态?

    讲了这么多原理,关键还是要落地——到底什么时候用哪个?我 了两个最常用的场景,你照着用准没错。

    静态包含:适合不变的公共部分,比如导航栏、Footer

    我之前做过一个企业官网项目,首页、关于我们、联系我们这几个页面的导航栏全是一样的,要是每个页面都写一遍导航栏代码,改个菜单得改五六个页面,累都累死了。后来用静态包含把导航栏写在header.jsp里,所有页面都用包含进去,改的时候只需要改header.jsp,所有页面都同步更新——是不是特别爽?

    但要注意啊:静态包含的被包含页面不能有、标签!之前有个实习生犯过这错,把整个首页的代码用静态包含进主页面,结果主页面的里又嵌套了一个,样式全乱了,后来把被包含页面的、、标签全删掉,才恢复正常。

    动态包含:适合实时更新的内容,比如广告、用户信息

    去年做电商项目时,首页的“限时折扣”模块我用了动态包含——这个模块要实时显示当前的折扣商品、剩余库存和倒计时,要是用静态包含的话,商品库存更新了也看不到,非得重启服务器才行。用动态包含的话,每次用户打开首页,服务器都会重新调用折扣模块的Servlet,查询最新的库存和价格,再把结果嵌进首页里,用户看到的永远是最新的信息。

    还有用户个性化内容,比如论坛的用户中心侧边栏,里面有用户的积分、等级和最新消息,这些内容都是实时变化的,用动态包含就很合适——每次打开页面都能获取当前用户的最新数据,要是用静态包含,用户积分涨了也看不到,非得刷新整个页面才行。

    再跟你说个避坑小技巧:动态包含传参数的时候,一定要注意编码问题!之前做论坛项目,我用动态包含传用户昵称,结果传过来的中文是乱码,后来在主页面和被包含页面都加了request.setCharacterEncoding("UTF-8"),才解决问题。还有啊,动态包含的被包含页面可以是JSP,也可以是Servlet,甚至是HTML——只要能输出内容就行,特别灵活。

    比如你想在首页显示实时的天气信息,就可以写个WeatherServlet,里面调用天气API获取数据,然后用把结果包含进首页,这样每次打开首页都能看到最新的天气,是不是很方便?

    其实 JSP的这两个包含功能,本质都是为了代码复用——但复用的方式不同,适用的场景也不同。你只要记住:不变的、公共的用静态,实时的、个性化的用动态,基本就不会踩坑了。我之前帮过的十几个JSP项目,都是这么用的,没出过错。

    对了,要是你实在拿不准,就先想:“这个部分会不会变?”——不会变的,选静态;会变的,选动态。就这么简单!


    你肯定碰到过这种情况——写主页面的时候定义了个String username = “张三”,然后用把header.jsp包含进来,结果编译框突然红了,报错说“变量username已经被定义”。其实这事儿特好理解,静态包含本质就是“编译时复制粘贴”啊!主页面要变成Servlet之前,会把被包含的header.jsp里的代码完完整整“贴”进自己的代码里,就跟你写文档时把另一个文档的内容复制过来一样。要是header.jsp里刚好也有个String username = “admin”,那合并后的代码里不就有两个一模一样的变量声明了吗?编译器哪分得清哪个是哪个?它肯定得给你报错啊——就像你在同一份作业里写了两次“我的名字叫小明”,老师也得问你“到底哪个才是真的?”。

    那咋解决?其实特简单,就俩招。要么你把其中一个变量名改了——比如把header.jsp里的username改成headerUsername,或者主页面的改成mainUsername,只要俩名字不一样,编译器就不会“脸盲”了;要么你直接换动态包含啊!动态包含是啥?就是运行的时候才去调用被包含的页面,俩页面的变量是分开的“小房间”——主页面的username在“房间A”,header里的username在“房间B”,根本不会撞一块儿。我之前帮隔壁组的小李改bug就碰到过这情况:他把用户中心的侧边栏用静态包含,结果主页面的userId和侧边栏的userId冲突了,点进去就报错。我跟他说“你换啊!”,他还犹豫说“那传参数会不会麻烦?”,我告诉他“你加个,侧边栏里用${param.userId}接就行,比改变量名省事多了”。结果他一改,立马就好了,还拍着我肩膀说“原来这么简单!我之前咋没想到?”——其实就是没搞懂静态包含“复制粘贴”的本质嘛!


    静态包含和动态包含可以互相替换吗?

    不能直接互相替换。两者底层逻辑完全不同:静态包含是编译时合并代码,适合不变的公共内容(如导航栏),能减少服务器编译压力;动态包含是运行时调用,适合实时更新的内容(如限时折扣、用户积分),能保证数据新鲜。若将静态内容换成动态包含,会增加不必要的运行时开销;若将动态内容换成静态包含,则无法实时更新数据。

    静态包含为什么会出现“变量重复定义”的错误?

    因为静态包含会在编译阶段把被包含页面的代码“复制粘贴”到主页面,若主页面和被包含页面定义了同名变量(比如都写了String username = “admin”),合并后的代码会出现两次变量声明,导致编译报错。解决方法很简单:要么修改其中一个变量的名字,要么把需要共享变量的场景换成动态包含(动态包含的变量相互独立,不会冲突)。

    动态包含传参数时中文显示乱码怎么办?

    这是编码不一致导致的。最有效的解决方法是统一请求编码:① 在主页面和被包含页面的开头都加上request.setCharacterEncoding(“UTF-8”),确保请求参数以UTF-8编码解析;② 若项目用了Servlet 3.0及以上版本,还可以在web.xml里配置一个CharacterEncodingFilter过滤器,全局设置请求编码为UTF-8,避免每次手动写编码代码。

    被包含页面有或标签会影响静态包含吗?

    会严重影响。静态包含是合并代码,若被包含页面有

    这类根标签,主页面的对应标签会被嵌套(比如主页面的里又多了一个),导致HTML结构混乱,样式和JavaScript都可能失效。所以静态包含的被包含页面,必须删除所有根标签,只保留具体内容(比如导航栏的

      菜单、Footer的

      版权信息)。

      动态包含可以包含Servlet或者HTML文件吗?

      当然可以。动态包含的核心是“运行时获取目标资源的输出结果”,不管目标资源是JSP、Servlet还是HTML,只要它能输出内容(比如Servlet生成的实时天气数据、HTML的静态广告),都能用包含。比如要在首页显示实时天气,写个WeatherServlet调用天气API,然后用就能把天气数据嵌进首页,用户每次打开都能看到最新信息。

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

    社交账号快速登录

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