指令元素
JSP指令元素主要包括3种:page指令、include指令及taglib指令。格式<%@ ...%>
1、页面指令:page,用来定义本jsp页面的固定属性。就是每段jsp文件开头那个,但该指令可以放在JSP页面中的任意位置。
page指令中除import属性外,其他属性只能在指令中出现一次。详细参数意义参考
2、taglib : 提供动作指令元素 , 作为初学者暂时不做介绍。
3、包含指令:include,格式为 <%@ include file=”path”%>。
避坑指南
不要试图<% <%@ include file=”path”%> %>这样包括它!要记住jsp中的<>表达式都是独立的!
除了部分注释:注释不能放在 jsp 动作元素的<></>中,例如不能放在<jsp:forward page='..'>...</jsp:forward>中,但是可以放在html的<></>中,例如<pre>...<!--"我是注释哈哈哈"-->...</pre>
输出表达式也可以“嵌套”进jsp中动作元素的<>的,例如下面的用户登陆demo中的:
<jsp:param value="<%=username%>" name="cuser"/> <!--注意引号-->
为什么这个可以呢?因为动作元素是支持变量、表达式的。<%=username%>相当于使用表达式取变量username的值 。
path是相对路径,不支持变量、表达式,不支持变量传递。/:是根目录,代表当前项目名文件夹下。如果想要
指定放在当前项目下的某个目录中可以通过/:指定路径。
我在WebContent目录下放了一个文件夹myfile,里面带有文件copyRight.jsp:
<body> <% out.println("jsp简单讲解3"); %> </body>下面就是我们的demo1:
<body> <%@include file="myfile/copyRight.jsp"%> </body>
完美显示了"jsp简单讲解3"~ 但是除了这个,还有一种include可以实现这种功能——
动作元素
1、包含文件:<jsp:include>
和指令元素中的<%@include%>区别在于:
jsp include 允许包含动态或静态文件,可以传递参数,path中可以有表达式或者变量。
执行速度上,<%@include>比<jsp:include>请求速度快。因为<%@ include file>是直接包含源代码,相当于直接“复制粘贴”,而 jsp 的还能传递参数,说明程序是“执行”它了的。
实际应用上,<%@include>用于检测用户是否登录、网站标识或网站的一些静态不变的信息;<jsp:include>用于发送一个请求,并接收返回的HTML,并可以加入参数。
且<%@ include file%>是把引入的文件和当前的文件共同合并成一个servlet文件进行解析。<JSP:include page>是把当前文件和引入文件生成两个不同的servlet文件,在当前文件中再进行动态的调用引入的servlet文件。
· 包含静态文件的使用格式: ( 注意最后 />,不是 > )
<jsp:include page=”path” flush=”true/false” /> flush是个实际上不怎么用到但是是个考点的属性
<jsp:include page="myfile/copyRight.jsp" /> 等价于demo1中的<%@include file=”myfile/copyRight.jsp”%>
· 包含动态文件的使用格式:(例如向被包含的动作页面中传递参数)
<jsp:include page=”path”flush=”true/false”>
<jsp:param name=”参数名称” value=”参数值”/>
</jsp:include>
本来想贴一段自己的代码,但是不得不说ecplise上开发jsp内置浏览器的延迟好严重啊,我都删行了,它还反复报错同一行同一列。
所以有时候看到旁边有个红叉叉,其实并不是你错了。而是eclipse没反应过来....大概和软件的时间戳设定有关?
别人的demo
2、请求转发:<jsp:forward>
即跳转页面,也是可以带参数,带值的。
· 静态中的格式:<jsp:forward page=”文件或标识路径的表达式”/>
· 动态中的格式:<jsp:forward page=”文件路径或标识路径的表达式”>
<jsp:param name=”参数名称1” value=”值1”/>
<jsp:param name=”参数名称2” value=”值2”/>
……
</jsp:forward>
下面就写个用户登陆,如果成功就跳转,不成功就不跳转的界面:
简易的登陆页面 login.jsp代码:
<body> <form action="check.jsp" method="get" name="form"> 输入姓名:<input type="text" name="user"><br> 输入密码:<input type="password" name="psw"><br> <input type=submit value="login" > </form> </body>
由代码可知我们获取到的用户名和密码数据都被传送到了check.jsp中判断该用户是否登陆成功:
构想一下java逻辑思路:
<% String username=request.getParameter("user"); String passward=request.getParameter("psw"); if(username.equals("admin")&&passward.equals("123")){ //跳转到欢迎页面 }else{ //返回登陆页面 } %>
可是我们知道,jsp中<>不能嵌套<>的(除了注释,以及动作元素中嵌套取值表达式)。
所以跳转页面怎么<jsp:forward>用到里面去?
emm...其实我们可以这样写:
<% String username=request.getParameter("user"); String passward=request.getParameter("psw"); if(username.equals("admin")&&passward.equals("123")){ %> //跳转界面 <% } else{ %> //回到登陆界面 <% } %>
一开始我也觉得挺神奇的,因为我一直认为一个<% .. %>就是一个独立的代码块,他们之间的变量是不能共享的,后来我去看了看tomcat下编译好的 java源码.....发现我错了,<%...%>看起来是分开的,但实际上一个 jsp 文件的页面中的所有<%...%>在java文件中都属于同一个代码块....... 好了我们可以继续完善我们的check.jsp了:
<body> <% String username=request.getParameter("user"); String passward=request.getParameter("psw"); if(username.equals("admin")&&passward.equals("123")){ %> <jsp:forward page='welcom.jsp'/> <% } else{ response.setHeader("refresh","3;url=login.jsp"); //设置停留在当前页面3秒,然后跳转到“login.jsp” %> <pre> 登陆失败!没有<%=username %>这个人!或者密码错误! 3s后跳转回登陆页面,跳转失败<a href="login.jsp">点击这里</a> </pre> <!-- pre格式的作用就是按照你的排版原样复制粘贴过去, 系统不会更改你在pre标签中写好的东西的排版。 比如在这里如果我不加pre标签,输出的界面就不是两行,两行字都归为一行去了。 --> <% } %> </body>
下面是我们的welcom.jsp,用于显示界面给用户的:
<body> welcom <%=request.getParameter("user") %> </body>
输出很正常,但是我们或许会纳闷!数据明明提交给了check.jsp页面!为什么welcom页面也会拿到值?
原因就是check.jsp中的<jsp:forward>在内部将request中带的数值传递给了welcom.jsp(具体可以看看java源码)。这是自己项目底层(或者说使用的服务器)上实现“内部传值”的过程,所以要注意的是jsp:forward只能传递参数给本项目的其它jsp代码,不要幻想着<jsp:forward page='别人的网站/jsp文件'>,别人是取不到我们的值的....。
那动态传值怎么传呢?很简单啊,把check.jsp上的<jsp:forward page='welcom.jsp'/>换成
<jsp:forward page='welcom.jsp'> <jsp:param value="<%=username %>" name="cuser"/> </jsp:forward>
然后welcom.jsp中的<%=request.getParameter("user") %> 换成<%=request.getParameter("cuser") %>
然后你会发现,其实welcom.jsp不做改动也是可以取值的!而且假如我们在check.jsp中的if(username.equals("admin")....)使用的是中文:username.equals("我自己"),还会乱码!输出:welcom ???
· 所以那我们干嘛要用动态传参?它适用于什么场景?
答案是适用于需要处理输入数据的场景,例如我之前举的加法例子,输入两个值,输出他们的和,其实就能应用在这:我们在login.jsp页面传入需要被计算的数值,然后在check.jsp中计算他们的和,并且通过<jsp:forward>转发给welcom.jsp显示数值~
我一直都很讨厌那些把简简单单的实例代码写的超级复杂繁琐的人,实际做项目写代码如果也这样不是会增加别人复习你代码的工作量么?例如在这个简单的用户登陆演示中我就不会用动态传参....扯多了,其实我也没啥好的代码习惯....
· 那我们怎么解决动作元素中传递参数的乱码问题?
首先为什么会出现这个问题,我们老师给的解释是:因为仅仅定义显示和输出的编码是不够的,我们还需要指定request的传递编码。身为一个合格的程序员必须记住:只要涉及到原理不同东西的数据传递都要注意转码问题....
request、response 中文乱码问题与解决方式+原理
知道为什么就很好解决了,直接查找api文档发现request中有设置编码的方式,加到代码中就行:
对了,使用这个的前提是:你传的是一个表格数据,否则无效!
.... request.setCharacterEncoding("UTF-8"); //加上 String username=request.getParameter("user"); ....