JSP(Java Server Page)和Servlet是Java EE规范的两个基本成员,是Java EE开发的基础知识,首先我们来学习JSP的一些基本语法。
这些基础知识的学习需要在自己的电脑上配置Tomcat服务器,Eclipse,以及Mysql。具体的配置这里不做讲解。
一、构建一个简单的Web应用(Hello World)
首先打开Tomacat的安装目录,找到webapps目录,在这个目录下创建一个文件夹,命名为WebTest,在WebTest文件夹中创建一个文件夹,命名为WEB-INF,然后在WEB-INF目录下创建两个文件夹,分别命名为classes和lib。其中classes和lib文件夹用来保存web应用所需要的Java类文件,classes文件夹用来保存后缀名为class的文件,lib文件夹用来保存JAR文件。然后在WEB-INF文件夹下创建一个文本文档,并将其改名为web.xml,这里要注意更改文本文档后缀名txt为xml。并且在web.xml文件中写入以下内容:
<?xml version="1.0" encoding="GBK"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
web.xml文件是我们web应用的配置描述符,我们可以通过修改这个文件的内容来配置管理我们Java Web应用的绝大部分组件,主要可以配置的内容有:1、配置JSP。2、配置和管理Servlet。3、配置和管理Listener。4、配置和管理Filter。5、配置标签库。6、配置JSP属性。7、配置和管理JAAS授权认证。8、配置和管理资源引用。9、Web应用首页。具体的web.xml配置,我们以后进行讲解。
通过上面的操作,我们可以构建出一个如下的目录结构:
<WebTest>(根目录)
|--WEB-INF
| |--classes(存放.class文件)
| |--lib(存放JAR文件)
| |--web.xml
|--a.jsp(这里可以放入多个.jsp文件,这些文件就是我们用JSP所编写的文件,可以通过浏览器来访问浏览。)
接下来我们需要编写a.jsp文件,实现我们的Hello World程序。
a.jsp内容如下:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
然后我们运行我们的Tomcat服务器,打开浏览器输入http://localhost:8080/WebTest/a.jsp,我们将在浏览器中看到p标签显示的内容 Hello World,这样我们就构建了一个简单的web应用。
二、JSP的基本原理
JSP的本质就是Servlet,我们编写的JSP代码主要由两个部分构成,第一个部分是静态的页面,也就是我们的HTML语言所编写的页面排版以及页面的内容,第二个部分是我们在JSP中用JAVA语言写的Java脚本程序,这一部分的内容是由Java的脚本程序动态生成的。下面是一个既包含静态内容又包含动态内容的JSP代码示例:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<p>3+5=</p>
<%
int a=3;
int b=5;
out.println(a+b);
%>
</body>
</html>
在上面的代码中,我们用p标签输出了“3+5=”,这一部分是静态内容,然后我们使用Java语言输出了8,这一部分是动态内容,Java语言要嵌入在Html中我们需要将Java语言写在<% %>标签中间。打开浏览器,输入url我们就可以看到浏览器上显示“3+5=8”。在一开始我们就说了JSP的本质就是Servlet,之所以这样说,是因为当我们将a.jsp文件放到我们的服务器然后通过浏览器访问的时候,首先服务器会先将我们的jsp文件编译成Servlet文件,然后Servlet文件通过输出流将内容输出到浏览器,这个Servlet文件存放在Tomcat服务器根目录下的work/Catalina/localhost/WebTest/org/apache/jsp目录下。下面我们就贴出上个例子中a.jsp编译出的Servlet文件:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.9
* Generated at: 2017-03-15 09:41:41 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.*;
public final class Test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
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 static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
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 java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}
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\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
out.write("<title>Insert title here</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<p>3+5=</p>\r\n");
int a=3;
int b=5;
out.println(a+b);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
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);
}
}
}
上面的Servlet代码主要有三个函数,分别是init,Destroy和service,init()函数主要负责初始化JSP/Servlet的方法,destroy()负责销毁JSP。Servlet之前的方法,service()是负责对用户的请求生成响应的方法。我们可以在service()这个函数中看到,原本在JSP代码中的html标签等静态内容在这个函数中有out.write()方法直接输出,而原来在JSP中的动态JAVA代码则是直接出现在这个函数中,去除了<% %>标签。也就是说当我们将jsp文件部署到服务器后,服务器会把我们的jsp文件按照上面的方式转为Servlet代码,然后Servlet代码的输出流会把我们的内容输出到浏览器中显示。