JSP 起源
- 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变。
- 如果使用Servlet程序来输出只有局部内容需要动态改变的网页, 其中所有的静态内容也需要程序员用Java程序代码产生,整个Servet程序的代码将非常臃肿,编写和维护都将非常困难。
- 为了弥补Servlet的缺陷, SUN公司在Servlet的基础.上推出了JSP( Java Server Pages )技术作为解决方案。
- JSP是简化Servle编写的-种技术,它将Java代码和HTML语句混合在同一个文件中编写,只对网页中的要动态产生的内容采用Java代码来编写,而对固定不变的静态内容采用普通静态HTML页面的方式编写。
JSP 运行原理
- WEB容器( Servlet引擎)接收到以.jsp为扩展名的URL的访问请求时它将把该访问请求交给JSP引擎去处理。
- 每个JSP页面在第-次被访问时, J SP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的dlass类文件,然后再由WEB容器( Servlet引擎)像调用普通Servlet程序-样的方式来装载和解释执行这个由JSP页面翻译成的SerMlet程序。
- JSP规范 也没有明确要求JSP中的脚本程序代码必须采用Java语言,JSP中的脚本程序代码可以采用Java语言之外的其他脚本语言来编写,但是,JSP页面最终必须转换成Java Servlet程序。
- 可以在WEB应用程序正式发布之前,将其中的所有JSP页面预先编译成Servlet程序。
JSP 的 9 个隐含变量
final javax.servlet.http.HttpServletRequest request
final javax.servlet.http.HttpServletResponse response
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
//还有一个exception 变量
- request:HttpServletRequest 的一个对象
测试 request
<br>
<%
String getNameByRequest = request.getParameter("user");
out.println(getNameByRequest);
%>
<hr>
- response: HttpServletResponse 的- 一个对象(在JSP页面中几乎不会调用response的任何方法.)
测试responses
<br>
<%
//查看response 的实现类
Class clazz = response.getClass();
out.println(clazz);
out.println(response instanceof HttpServletResponse);
%>
<hr>
- pageContext:页面的上下文,是PageContext的一个对象。可以从该对象中获取到其他8个隐含对象。也可以从中获取到当前页面的其他信息。
测试pageContext
<br>
<%
ServletRequest req = pageContext.getRequest();
//得到的 request 否和定义的request 相同
out.println(req == request);
%>
<hr>
- session: 代表浏览器和服务器的一次会话,是HttpSession的一个对象。
测试session
<br>
<%
out.println(session.getId());
%>
<hr>
- application: 代表当前WEB应用。是ServletContext 对象。
测试application
<br>
<%
out.println(application.getInitParameter("password"));
%>
<hr>
``
6. config: 当前JSP对应的Servlet的ServletConfig对象(几乎不使用)。若需要访问当前JSP配置的初始化参数,
```java
测试config
<br>
<%
//记得改 url 地址
String name = config.getInitParameter("name");
out.println(name);
%>
<hr>
- out: JspWriter 对象。调用out . println() 可以直接把字符串打印到浏览器上。
- page: 指向当前JSP对应的Servlet 对象的引用, 但为object 类型,只能调用0bject 类的方法(几乎不使用)
测试page
<br>
<%
out.println(this);
out.print("<br>");
out.println(page);
%>
测试结果
对于exception
注:
pageContext ,request ,session ,application 对属性的作用范围从小到大
JSP 模板
- JSP 模板元素:JSP页面中的静态HTML内容总称
- JSP表达式( expression )提供了将一个java变星或表达式的计算结果输出到客户端的简化方式,它将要输出的变星或表达式直接封装在<%=和%>之中。
<!-- JSP 表达式 -->
<%= new Date() %>
- JSP脚本片断( scriptlet )是指嵌套在<%和%>之中的-条或多条Java程序代码。多个脚本片断中的代码可以相互访问
<%
Boolean flag = true;
if(flag){
%>
我出来了
<%
}else{
%>
我死掉了
<%
}
%>
- JSP声明: JSP声明将Java 代码封装在<% !和%>之中,它里面的代码将被插入进Servlet的,_jspService 方法的外面(在JSP页面中几乎从不这样使用)
- JSP注释的格式: <%-- JSP注释–%> JSP注释可以阻止Java代码的执行.HTML 注释不变
<!-- JSP 注销Java 代码 -->
<%--
<%
System.out.println("HelloWorld!");
%>
--%>
和属性相关的方法
pageContext, request, session, application 对象都有这些方法!
- object getAttribute(String name):获取指定的属性
- Enumeration getAttributeNames(): 获取所有的属性的名字组成的Enumeration 对象
- removeAttribute(String name): 移除指定的属性
- void setAttribute(String name, object o):设置属性
测试:
第一个jsp 文件中代码
<h1>Attr1 Page</h1>
<br><br>
pagecontextAttr:<%= pageContext.getAttribute("pageContextAttr") %>
<br><br>
requestAttr:<%= request.getAttribute("requestAttr") %>
<br><br>
sessionAttr:<%= session.getAttribute("sessionAttr") %>
<br><br>
applicationAttr:<%= application.getAttribute("applicationAttr") %>
<br><br>
<a href="day0201a.jsp">go to day0201a page</a>
第二个 JSP 文件中代码:
<h1>Attr2 Page</h1>
<br><br>
pagecontextAttr:<%= pageContext.getAttribute("pageContextAttr") %>
<br><br>
requestAttr:<%= request.getAttribute("requestAttr") %>
<br><br>
sessionAttr:<%= session.getAttribute("sessionAttr") %>
<br><br>
applicationAttr:<%= application.getAttribute("applicationAttr") %>
结果:
注:
pageContext: 属性的作用范围仅限于当前的JSP 页面
request:属性的作用范围仅限于同一个请求
session: 属性的作用范围限于一次会话:浏览器的打开直到关闭称之为一次对(在此期间会话不失效)
application: 属性的作用范围限于当前 web 应用,是范围做大的属性作用范围,只要在一处设置属性,在各处的 servlet 或者是 JSP 中都可获取到
请求重定向 与 请求转发
测试请求转发:
创建 aServlet.java 的 servlet 文件
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("this is aServlet");
//设置一个 name 属性
request.setAttribute("name", "AServletAttr");
System.out.println("name---->"+request.getAttribute("name"));
//请求的转发
//转发路径
String path = "bServlet";
//得到ResquestDispatcher 对象
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/"+path);
//转发请求
requestDispatcher.forward(request, response);
}
创建 bServlet.java 的 servlet 文件
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("This is BServlet");
System.out.println("name---->"+request.getAttribute("name"));
}
测试请求重定向:
创建 aPage.java 的 servlet 文件
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("This is aPage");
//设置 name 属性
request.setAttribute("name", "APageAttr");
System.out.println("name--->" + request.getAttribute("name"));
//请求重定向
response.sendRedirect("bPage");
}
创建 bPage.java 的 servlet 文件
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("This is bPage");
System.out.println("name--->" + request.getAttribute("name"));
}
测试的JSP文件;
<body>
<h2>Attr Page</h2>
<br><hr>
<a href="aServlet">go to Attr1</a>
<br><br>
<a href="aPage">go to APage</a>
</body>
结果:
点击 go to Attr1 请求转发页面:
点击 go to APage 请求重定向超链接
请求转发与请求重定向的本质区别:
请求转发像服务器发送了一次请求,request 和 response 用的是一个(打印结果可以看出)
请求重定向向服务器发送了两次请求,request 和 response 用的不是一个(可看出)
具体区别
- 请求的转发:地址栏是初次发出请求的地址
请求的重定向:地址栏不再是初次发 出的请求地址。地址栏为 最后响应的那个地址 - 请求转发:在最终的Servlet中,request 对象和中转的那个request 是同一个对象. .
请求的重定向:在最终的Servlet中,request 对象和中转的那个request不是同一个对象. - 请求的转发:只能转发给当前WEB应用的的资源
请求的重定向:可 以重定向到任何资源。 - 请求的转发: / 代表的是当前WEB应用的根目录
请求的重定向: / 代表的是当前WEB站点的根目录。