1.jsp页面中的注释 comment
第一种:
<!-- html/xml中的注释方式 -->
特点:
1.用户在浏览器中右键查看源代码 [能] 看到这个注释。
2.在服务器端,这个jsp页面被翻译成的java文件中 [能] 看到这个注释.
注意: 【jsp动作元素】 放在这种注释里面依旧有用,【注释不起作用】,失效了!
例如:
<!-- <jsp:forward page="main.jsp"></jsp:forward> -->
第二种:
<%--
jsp中的注释方式【隐藏注释】
--%>
特点:
1.用户在浏览器中右键查看源代码 [不能] 看到这个注释。
2.在服务器端,这个jsp页面被翻译成的java中 [不能] 看到这个注释.
第三种:
java中的注释方式,但是这种注释方式只能在【jsp的脚本】或者【声明】中使用。
//String name = "tom";
/*
int b = 40;
*/
/**
int a = 20;
*/
特点:
1.用户在浏览器中右键查看源代码 [不能] 看到这个注释。
2.在服务器端,这个jsp页面被翻译成的java中 [能] 看到这个注释.
2.内置对象
在jsp页面代码中不需要声明,直接可以使用的对象。
其实是只有在这个【_jspService()】方法中才能使用
jsp脚本和jsp表达式
<% 脚本 %>
<%= 表达式 %>
2.1 所有内置对象
一共有【9个内置对象】可以直接使用.
类型 名字
PageContext pageContext
HttpServletRequest request
HttpSession session
ServletContext application
Object page
HttpServletResponse response
JspWriter out
ServletConfig config
Throwable exception 【isErrorPage才可以用】
注意:在生成的中间java文件中,源码可以观察到它们的声明和定义。
注意:为什么这些对象可以直接使用,因为他们都是在_jspService这个方法中默认声明了出来.而我们在表达式和脚本中所写的java代码将来是要翻译到_jspService方法中的,所以我们在表达式和脚本中写java代码的时候可以直接使用这些对象.
2.2 范围对象
范围对象有四个,在一定范围内可以存取数据。
pageContext 【比request小】
页面范围(只能在同一个页面中起作用)
request
在同一次请求中
session
在一次会话中
application
在应用中
测试:
在一个页面中通过上述 对象.setAttribute("name","tom");
然后页面跳转 <%=对象.getAttribute("name") %>
page
page指的是中间类对象,【jsp页面会被翻译生成一个java类】,服务器使用这个java类【创建的对象】就是page。
把page值输出即可看到,所以说page对象代表jsp页面本身。
这个对象一般用不到,了解即可。
response
往浏览器发送数据时会用到。
但在jsp里面用的不多,因为已经有了 out。所以一般只在【重定向时才用】。
response.sendRedirect("test.jsp");
out
n用于向浏览器输出内容的输出流.
n看中间生成的源码,由response得到pageContext,再获得out.
config
它的方法主要有四个,在jsp内实际上没有用。
nconfig.getServletName();
返回值为jsp,不是原来的servlet了。
config.getServletContext();
获取app,不需要,观察application与之是否相同。
config.getInitParameter(name);
需要在web.xml配置参数,所以现在基本废弃
config.getInitParameterNames();
同上 废弃
exception
跳转后显示页面错误。【前面专门讲过】
这个对象我们并不能直接使用,需要isErrorPage="true"设置后才能使用,这个可以算是一个隐藏对象.
这个对象表示将来这个jsp页面运行出错的时候所抛出的异常对象.
以上就是9种内置对象,必须完全掌握
*************************** ****************
3.jsp页面中的路径
一般情况下,jsp中路径问题是和我们之前在servlet中讨论的html里面的路径问题是一样的,但是在【jsp中可以动态获得该项目的url】。
如果在jsp页面的上面写了这样一个脚本:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
并且再<head>标签中加入了一个子标签:
<base href="<%=basePath%>" />
那么在这个jsp页面中,我们再去写上一个相对路径(最左边没有加/的那种路径),它就不是相对于地址栏中的当前路径了,而是要相对于这个basePath变量所代表的这个路径.
使用test/test.jsp中的超链接进行测试。
4.EL表达式
形式:${ }
作用:从一个【范围对象里面取值】或者从一个对象中取值或是向页面输出值.
之前我们使用<% ... %>等形式,并不够简洁。
例如:
<% request.setAttribute("name","zs") %>
<%=request.getAttribute("name") %>
可以简写为:
${name } 类似mybatis中的${id}
注意:el表达式只适用于四种范围对象里面存放的数据。
4.1 接收客户端url传递的参数
${param.name1 }
等同于
<%=request.getParameter("name1") %>
看源码发现 java代码实现了其功能。
注意:不管是get还是post,都可以获取到参数值。
4.2 指定范围取值
${pageScope.pname }
${requestScope.rname }
${sessionScope.sname }
${applicationScope.aname }
如果上述代码想要得到结果,得先执行下面代码,将值放入。
<%
pageContext.setAttribute("pname","1");
request.setAttribute("rname","2");
session.setAttribute("sname","3");
application.setAttribute("aname","4");
%>
4.3 不指定范围内取值
${name }
按照范围从小到大顺序,即pageContext request session application依次去找叫name的值。
一旦找到了就输出,最终没有找到就什么都不输出。
<%
pageContext.setAttribute("name","p1");
request.setAttribute("name","r2");
session.setAttribute("name","s3");
application.setAttribute("name","a4");
%>
4.4 取出一个对象中的属性值.
先准备一个值
<%
Student s = new Student(1,"zs",20);
request.setAttribute("student",s);
%>
然后去获取值
${requestScope.student.id} 先获得s然后再获取id值
${requestScope.student.name}
${requestScope.student.age}
或者
${student.id }
找对应的get方法调用获取值。
${student.name }
${student.age }
${student.score }
//只要有getScore()方法即可,而非score属性
也可以 ${student.addr.city } 其中addr是子对象。
或者
有时候student并非对象,比如(student.id,request.setAttribute("student.id","10"));被当成了一个名字,
对于这样的特殊情况,可以使用下面的形式获取值。
${student["id"]}
${student["name"]}
${student["age"]}
注意:${student.id}表示是要调用student对象中的getId方法,至于对象中有没有id属性对这个操作没有任何影响.所以这和id指的是对象中的property而不是attribute。
如果Student类中一个方法是getAddress,返回一个Address类的对象,Address类中有一个方法getCity,这个时候我们就可以这样写去拿到city属性的值.
${student.address.city}
4.5 输出字符串
${"hello" }
注意,${hello } 是取值,而非输出字符串
实际应用:
${"hello" == 表达式的值}
4.6 输出运算结果或者boolean表达式
${1+1 }
${(1+2)*3-4+5*3 }
${1<3 }
【空测试】
${empty "" }
为空的话返回true
${empty "hello" }
又例如:
<%
String str="go"; | str = "";
request.setAttribute("str",str);
%>
${empty str }
//也可以判断变量
【取否】 不为空的话返回true
${not empty "hello" }
${! empty "hello" }
【条件判断】
${param.score>50 }
${param.score>60?"good":"bad" }
7.获取并输出数组、集合中的元素值
先准备数据放入request里面
<%
String[] str = {"hello","world"};
List<String> list = new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("a",100);
map.put("b",200);
map.put("c",300);
request.setAttribute("str",str);
request.setAttribute("list",list);
request.setAttribute("map",map);
%>
数组和list可以直接下标取值
${str[0] }<br>
${list[1] }<br>
map通过key值取值
${map["c"] }<br>
*********************
五.JSTL标签库
JSTL: JSP Standard Tag Library
JSTL根据功能可以分成很多种类:核心标签库、格式化标签库、数据库标签库等。
我们关心的是核心标签库core部分。
和【EL配合】使用,可以让用户【尽可能少的使用java源码】。
需要先导入jstl的jar包。 jstl.jar standard.jar
1.让web项目支持JSTL标签库
在eclipse中,建一个文本项目,默认都是不支持JSTL,所以需要我们自己把JSTL的jar包导入到项目中(复制粘贴到项目中的lib目录):jstl.jar standard.jar
2.把JSTL标签库导入到jsp页面中
使用jsp中的taglib指令,将标签库引入:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
注意,加前缀避免与其他人写的标签重名。
【uri的值可以自动提示补全】。
prefix="c"相当于给这个标签库起一个别名,将来在页面中就是用以c开头的标签来使用标签库中的标签。这个别名也可以叫其他的名字。
<c:forEach>标签
循环遍历操作,【使用率最高】。
先准备一个集合:
<%
List<Student> list = new ArrayList<Student>();
list.add(new Student(12,"tom1",21));
list.add(new Student(21,"tom2",22));
list.add(new Student(34,"tom3",23));
list.add(new Student(14,"tom4",24));
request.setAttribute("list", list);
%>
使用<c:forEach>标签 【完整代码】 遍历
<c:forEach var="stu" items="${list }" begin="0" end="3" varStatus="status" step="1">
${status.index } : ${stu.id } - ${stu.name } - ${stu.age } <br>
</c:forEach>
varStatus表示循环的状态,用status表示。
step是每次跳过几个,默认值为1,逐个遍历。
el表达式十分强大,基本可以写到任何地方。
注意:
begin="" 默认值是0,
end ="" 默认值是最后一个元素,
一般遍历只要写var和items来个属性即可。
【常规写法】:
<c:forEach items="${list }" var="stu">
${stu.id } | ${stu.name } | ${stu.age } <br>
</c:forEach>
【遍历List集合】:
list是放进request对象中的一个List集合,集合中存放的是Student类型的对象.
items=""属性值是要遍历的集合
var="" 属性值是每次遍历到的对象用什么名字的变量去接收。
<table>
<c:forEach items="${list }" var="stu">
<tr>
<td>${stu.id }</td>
<td>${stu.name }</td>
<td>${stu.age }</td>
</tr>
</c:forEach>
</table>
【遍历Map集合】:
准备数据
<%
Map<Integer,Student> map = new HashMap<Integer,Student>();
map.put(76,new Student(76,"tom1",21));
map.put(42,new Student(42,"tom2",25));
map.put(31,new Student(31,"tom3",21));
map.put(88,new Student(88,"tom4",20));
session.setAttribute("map",map);
%>
map是一个Map类型的集合,放到了session对象中,entry是我们定义的一个变量,用做接收每次遍历到的集合中的一组键值对。
我们可以通过entry.key, entry.value分别拿到这次遍历到的key值和value值。
<c:forEach items="${map }" var="entry">
${entry.key }-->${entry.value.id } ${entry.value.name } ${entry.value.age }<br>
</c:forEach>
<c:if>标签:
条件判断
<%
request.setAttribute("score",90);
%>
<c:if test="${score>85 }">
<font color="red">你的分数超过了85分</font>
</c:if>
<c:if test="${score>95 }">
<font color="blue">你的分数超过了95分</font>
</c:if>
这样写相当于:
if(score>85){
...
}
if(score>95){
...
}
<c:choose>标签
<c:when>标签
<c:otherwise>标签
例如:
<c:set scope="request" var="score" value="85"></c:set>
<c:choose>
<c:when test="${score>=90 }">优</c:when>
<c:when test="${score>=80 }">良</c:when>
<c:when test="${score>=70 }">中</c:when>
<c:when test="${score>=60 }">及格</c:when>
<c:otherwise>差</c:otherwise>
</c:choose>
相当于:
if(score>=90){
}else if(score>=80){
}else if(score>=70){
}eles if(score>=60){
}else{
}
<c:import>标签
和<jsp:include>的作用基本相同
<c:import url="main.jsp"></c:import>
将main.jsp页面导入当前jsp中。
//先放入date,然后再引入date即可
<c:import var="data" url="main.jsp" />
<c:out value="<a href=''>测试</a>"></c:out>
<c:out value="${data }"></c:out>
${data }
注意【观察c:out】 与上述标签${data }区别。
我们发现 c:out 有点类似CDATA,没有解析过程。
<c:redirect>
重定向标签
<c:redirect url="main.jsp"/>
<c:out>标签
向页面输出内容,就像<%=... > ${ }
但是可以输出表达式。
<c:out value="hello"></c:out>
<c:out value="${5+5 }"></c:out>
//list是放在request中的List集合,集合里面是Student对象
<c:out value="${list[2].id }"></c:out>
<c:set>标签:
向某一个范围对象[pageContext,request,session,application]中存放一个值。
<c:set var="name" value="zhangsan" scope="request"></c:set>
往scope范围中放入一个值。
测试:
<c:out value="${requestScope.name }"></c:out>
<c:remove>标签:
从某个范围对象中把某个值给移除掉
<c:remove var="name" scope="request"/>
再次打印,就没有了
<c:out value="${requestScope.name }"></c:out>
<c:catch>标签
处理产生错误的异常状况,并且将错误信息储存起来。
<c:catch var="catchException">
<% int x = 5/0; %>
</c:catch>
<c:if test = "${catchException != null}">
<p>异常为 : ${catchException } <br />
发生了异常: ${catchException.message }</p>
</c:if>