一、JSP的概念
学完Servlet技术,轮到学新技术了JSP
话说之前学的糊里糊涂,对Servlet技术具体有什么用还不是很了解,今天对照JSP技术的作用,有些明白
简单来说,Servlet技术是在java写html的技术,JSP技术是在html写java的技术
官方的话是这样说地:
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
为什么会出现这中技术,话说是用Servlet写html页面很费劲
比如这个(是不是很费劲呀):
package com.java.jsp;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Demo1 extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在Servlet中输出HTML内容十分的不方便
//并且为html增加js和css等控制时十分的不方便
response.getWriter().write("<from action='' method='' οnsubmit='checkForm()'>" +
"<input type='text' name='username'/>"+
"<input type='password' name='password'/>"+
"</form>");
response.getWriter().write("function checkForm(){" +"" +
"" +
""+
"}");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
如果用JSP写的话就变得很简单了,来看一个简单的jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'showtime.jsp' starting page</title>
</head>
<body>
<%
Date date = new Date();
String dateStr = date.toLocaleString();
out.write(dateStr);
%>
</body>
</html>
二、JSP技术的原理
JSP为什么能够可以将数据输出浏览器?原理是怎么样的?
其实JSP是可以编译成Servlet,它看以看作是一种Servlet
那么上面的例子的showtime.jsp编译在哪里了?我们可以在这个目录下:
tomcat\work\Catalina\localhost\Day05\org\apache\jsp
找到编译后的jsp,里面写了什么东西,看下面?
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2015-06-16 15:30:55 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class showtime_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
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;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write(" <title>My JSP 'showtime.jsp' starting page</title>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" ");
Date date = new Date();
String dateStr = date.toLocaleString();
out.write(dateStr);
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
里面虽然东西一大堆,但对比jsp,我们可以看出几个关键的部分:
1、这是八大XX(目前还不了解),这八大XX可以在JSP直接写出来,不用再定义
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;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
2、这就是html的标签了:
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write(" <title>My JSP 'showtime.jsp' starting page</title>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" ");
Date date = new Date();
String dateStr = date.toLocaleString();
out.write(dateStr);
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
里面有个值得注意的是java代码:
Date date = new Date();
String dateStr = date.toLocaleString();
out.write(dateStr);
这就是直接写的java代码
三、jsp语法
下面先逐一介绍JSP模板元素、JSP表达式、JSP脚本片段、JSP声明、JSP注释。还有些内容请看后面文章
1、JSP模版元素
jsp页面中书写的HTML内容称作JSP的模版元素,在翻译过来的Servlet中直接被out.write()输出到浏览器页面上了
如上面的(剔除java代码):
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write(" <title>My JSP 'showtime.jsp' starting page</title>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
2、JSP表达式
<%= java表达式 %> 在翻译过来的Servlet中,计算java表达式的值后,被out输出到浏览器上
3、JSP脚本片断
概念?
<% 若干java语句 %> 在翻译过来的Servlet中,直接被复制粘贴到了对应的位置执行.
在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素
多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况
单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句
简单来说就是包含在<%%>中的java代码
下面的就是: <%
Date date = new Date();
String dateStr = date.toLocaleString();
out.write(dateStr);
%>
概念后面的三句话是什么意思?
可以这样理解:
jsp中有很多对<%%>,里面的java代码可以是完整的,也可以不是完整的,但是这么多<%%>一起结合起来必须是完整的java代码
不明白?看下面的例子,这个例子与上面的同效:
<% Date date = new Date();%>
<% String dateStr = date.toLocaleString();%>
<% out.write(dateStr); %>
4、JSP声明
<%! 若干java语句 %> 在翻译过来的Servlet中会被放置到和Service方法同级的位置,变成了类的一个成员
注意里面有个!号
如下面:
<%! int i = 0; %>
<%! public void method1(){} %>
<%! static{} %>
<%! {} %>
<%! class someclass{} %>
<%! int a = 0;%>
那么翻译成Servlet它会处于什么样的地位?
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2015-06-17 06:43:13 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class jspDemo2_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
int i = 0;
public void method1(){}
static{}
{}
class someclass{}
int a = 0;
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
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;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write(" <title>My JSP 'jspDemo2.jsp' starting page</title>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" ");
out.write("\r\n");
out.write(" \t");
out.write("\r\n");
out.write(" \t");
out.write("\r\n");
out.write(" \t");
out.write("\r\n");
out.write(" \t");
out.write("\r\n");
out.write(" \t\r\n");
out.write(" \t");
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
仔细看的话发现他们都成为了类的变量
在这里注意两个细节
1、下面的写法是错误的
<%! public void method1(){
out.write("我是错误的");
} %>
原因你懂的,因为out是局部变量,method()是成员方法
2、写好了jsp,只有在浏览器访问的时候才会编译成Servlet而且编译一次后就不用再编译了
5、jsp注释
有三大注释:
<%-- 注释的内容 --%> 被jsp注释注释掉的内容,在jsp翻译引擎将jsp翻译成Servlet的过程中会被丢弃,在翻译过来的Servlet中没有这些信息
<%//java注释%> java注释被当作jsp脚本片段被翻译到了Servlet中,在.java文件被翻译成.class文件的时候注释信息被丢弃
<!-- HTML注释 --> html注释被当作模版元素输出到了浏览器上,浏览器认识html注释不予显示
下面给一个综合的例子,看看jsp表达式、jsp脚本片段、jsp声明和注释在转换成servlet分别有什么不同
test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
</head>
<body>
<%//jsp表达式 %>
<%=new String("这是jsp表达式") %>
<%//jsp片段 %>
<%
String str=new String("这是jsp脚本片段");
out.write(str);
%>
<%//jsp声明 %>
<%!int i=0; %>
</body>
</html>
然后在浏览器中输入:http://localhost/Day06/test.jsp 可得到
然后看看源代码
为什么上面的jsp脚本和表达式有点相似?
我们可以将转换过来的servlet看一看,在下面的目录
打开看看,里面是什么?
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.42
* Generated at: 2015-08-04 15:24:45 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
int i=0;
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
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;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" ");
//jsp表达式
out.write("\r\n");
out.write(" ");
out.print(new String("这是jsp表达式") );
out.write("\r\n");
out.write(" \r\n");
out.write(" ");
//jsp片段
out.write("\r\n");
out.write(" ");
String str=new String("这是jsp脚本片段");
out.write(str);
out.write("\r\n");
out.write(" \r\n");
out.write(" ");
//jsp声明
out.write("\r\n");
out.write(" ");
out.write("\r\n");
out.write(" \r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在上面已经知道
jsp声明已经变成了成员变量
而jsp注释也变成了java的注释
而jsp表达式可看成<%= %>中的等号,变成了out.write();相似的作用
而jsp片段就相当于java代码