单纯用Servlet其实可也写网页, 只要把网页内容全部调用response.getWritter方法把整个网页写进去就可以了, 但是这样很笨比, 显然不能这么写;
就像PHP一样, jsp是把java语言直接内嵌写在html里面;
开头这样写
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
在导入其他类的时候
,如果导入多个类,彼此用,逗号隔开,像这样 import="java.util.*,java.sql.*"
jsp的本质其实是Servlet, 编译之后jsp会被编译成Servlet;
jsp由这些页面元素组成:
- 静态内容
就是html,css,javascript等内容 - 指令
以<%@开始 %> 结尾,比如<%@page import=“java.util.*”%> - 表达式 <%=%>
用于输出一段html - Scriptlet
在<%%> 之间,可以写任何java 代码 - 声明
在<%!%> 之间可以声明字段或者方法。但是不建议这么做。 - 动作
<jsp:include page=“Filename” > 在jsp页面中包含另一个页面。在包含的章节有详细的讲解 - 注释 <%-- – %>
不同于 html的注释 通过jsp的注释,浏览器也看不到相应的代码,相当于在servlet中注释掉了
<%=%>和 <%out.println()%>是等价的, 就是输出一个字符串;
所以比如说要用for循环来输出一个表格应该这样做:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%
List<String> words = new ArrayList<String>();
words.add("today");
words.add("is");
words.add("a");
words.add("great");
words.add("day");
%>
<table width="200px" align="center" border="1" cellspacing="0">
<%for (String word : words) {%>
<tr>
<td><%=word%></td>
</tr>
<%}%>
</table>
jsp中有include这个东西, 可以是一个指令也可以是一个动作,
如果是指令include
<%@include file="footer.jsp" %>
footer.jsp的内容会被插入到 hello.jsp 转译 成的hello_jsp.java中,最后只会生成一个hello_jsp.java文件
如果是动作include
<jsp:include page="footer.jsp" />
footer.jsp的内容不会被插入到 hello.jsp 转译 成的hello_jsp.java中,还会有一个footer_jsp.java独立存在。 hello_jsp.java 会在服务端访问footer_jsp.java,然后把返回的结果,嵌入到响应中。
因为指令<%@include 会导致两个jsp合并成为同一个java文件,所以就不存在传参的问题,在发出hello.jsp 里定义的变量,直接可以在footer.jsp中访问。
而动作<jsp:include />其实是对footer.jsp进行了一次独立的访问,那么就有传参的需要。
如本例:
- 在hello.jsp中使用动作<jsp:include,并通过<jsp:param 带上参数
<jsp:include page="footer.jsp">
<jsp:param name="year" value="2017" />
</jsp:include>
- 在footer.jsp中,使用request.getParameter(“year”)取出year
所以我觉得还是用指令比较好;
JSP做客户端和服务器端跳转也和Servlet里一样可以:
response.sendRedirect("hello.jsp");//客户端跳转
request.getRequestDispatcher("hello.jsp").forward(request, response);//服务器端跳转
<jsp:forward page="hello.jsp"/>//使用jsp的指令简化的来做服务器端跳转
在JSP中可以使用Cookie
设置Cookie:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
Cookie c = new Cookie("name", "Gareen");
c.setMaxAge(60 * 24 * 60);
c.setPath("/");
response.addCookie(c);
%>
<a href="getCookie.jsp">跳转到获取cookie的页面</a>
然后是获取Cookie的方法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
Cookie[] cookies = request.getCookies();
if (null != cookies)
for (int d = 0; d <= cookies.length - 1; d++) {
out.print(cookies[d].getName() + ":" + cookies[d].getValue() + "<br>");
}
%>
同样的在JSP中也可以用Session, 设置Session:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
session.setAttribute("name", "teemo");
%>
<a href="getSession.jsp">跳转到获取session的页面</a>
获取Session内容的方法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
String name = (String)session.getAttribute("name");
%>
session中的name: <%=name%>
Session和Cookie的区别有一个很重要的点在于, 其实Session是保存在服务器端的, 而Cookie是保存在客户端本身的;
如果不是第一次访问浏览器的话, 客户端本身是有Cookie的, 那么会同时传过去一个jsessionid, 这就会在服务器端对应一个Session, 这时候服务器端就不会创建一个新的Session, 而是根据这个id找到之前已经创建过的Session;
如果浏览器把cookie功能关闭,那么服务端就无法获取jsessionid,每一次访问,都会生成一个新的session对象。
没有Cookie的时候, 如果还是想要找到之前的session, 可以这样做:
response.encodeURL("getSession.jsp")
response.encodeURL方法会把getSession.jsp这个url转换为
getSession.jsp;jsessionid=22424AEA86ADBE89F335EEB649D997A8
通过这个方式,提交jsessionid到服务器。 服务器根据这个jsessionid匹配到对应的session. 与session相关的功能,就可以正常工作了。
在jsp里面这样:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
session.setAttribute("name", "teemo");
%>
<a href="<%=response.encodeURL("getSession.jsp")%>">跳转到获取session的页面</a>
然后在默认的tomcat配置中, session会保存30分钟;
JSP有4个作用域
1.pageContext 当前页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
pageContext.setAttribute("name","gareen");
%>
<%=pageContext.getAttribute("name")%>
2.requestContext 一次请求
requestContext指的是一次请求
如果发生了服务端跳转,从setContext.jsp跳转到getContext.jsp,这其实,还是一次请求。 所以在getContext.jsp中,可以取到在requestContext中设置的值
客户端跳转,浏览器会发生一次新的访问,新的访问会产生一个新的request对象。
所以页面间客户端跳转的情况下,是无法通过request传递数据的。
常用写法是
request.setAttribute("name","gareen");
request.getAttribute("name")
但是也可以用pageContext来做,写成
pageContext.setAttribute("name","gareen",pageContext.REQUEST_SCOPE);
pageContext.getAttribute("name",pageContext.REQUEST_SCOPE)
3.sessionContext 当前会话
jsp里面这样写
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.setAttribute("name","gareen");
response.sendRedirect("getContext.jsp");
%>
也可以这样:
pageContext.setAttribute("name","gareen",pageContext.SESSION_SCOPE);
pageContext.getAttribute("name",pageContext.SESSION_SCOPE)
4.applicationContext 全局,所有用户共享
可以这样写:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
application.setAttribute("name","gareen");
System.out.println(application == request.getServletContext());
response.sendRedirect("getContext.jsp");
%>
也可以这样
pageContext.setAttribute("name","gareen",pageContext.APPLICATION_SCOPE);
pageContext.getAttribute("name",pageContext.APPLICATION_SCOPE)
JSP的隐式对象指的是不需要显示定义,直接就可以使用的对象
JSP一共有9个隐式对象,分别是
request,response,out
pageContext, session,application
page,config,exception
request,response,out
request, response, out 就对应 请求, 响应, 和直接输出到网页上;
page,config,exception
page 对象即表示当前对象
JSP 会被编译为一个Servlet类 ,运行的时候是一个Servlet实例。 page即代表this
config可以获取一些在web.xml中初始化的参数。
在JSP中使用config比较复杂,需要如下几个步骤
- 在web.xml中进行配置
- 创建一个testconfig.jsp
通过config.getInitParameter(“database-ip”) 获取参数 - 访问路径,获取web.xml中配置的参数
exception 对象只有当前页面的<%@page 指令设置为isErrorPage="true"的时候才可以使用。
同时,在其他页面也需要设置 <%@page 指令 errorPage="" 来指定一个专门处理异常的页面。
-
准备一个try.jsp
设置errorPage=“catch.jsp”,表示有异常产生的话,就交给catch.jsp处理
故意在里面造成数组越界异常 -
准备一个catch.jsp
设置 isErrorPage=“true”,表示当前页面可以使用exception对象