JSP全称jave server pages。jsp是服务端的技术,需要服务器编译翻译成servlet才能使用。jsp出现之前一直是HTML在做web的显示工作,用户通过http请求访问网站,servlet将内部html资源跳转过去供用户浏览。但是那些静态资源的展示不足以满足用户的需求,网站的定位更多的在于提高访问量,获取更多的用户信息。一开始通过使用servlet的response.write()在服务端将一些动态的信息发送到显示界面,我们的serlvet程序看起来会非常的臃肿,难以维护和扩展。于是jsp的出现很好的弥补了servlet的短板,它用来展示一些动态的数据使得开发人员的开发效率大大提高。并且简单易学,不熟悉servlet开发的也可以使用jsp技术完成网站开发。
不能说是jsp替代了servlet,只能说它是servlet的强力助手,因为这样一来,我们的网站结构中servlet只业务逻辑和转发,jsp只用来做界面展示。
在jsp中我们可以写java代码,也可以写html标签,又能使用css、jquery技术,所以说jsp是各种技术的结合,并且技术之间的耦合性几乎没有。
为什么说jsp就是sevlet
在服务器端编写好jsp代码时,发布应用后,我们的web目录中会出现work的目录,是用来存放编译后的jsp的.java代码和class文件。如图
那再来看看java文件中的内容
开头部分的注释是由服务器jsp引擎编写的,指出jsp的被创建者,创建时间,最后修改时间
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.64
* Generated at: 2016-12-09 13:43:59 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.
*/
导包部分,默认的三个包和一个代码中使用到的util的包
package org.apache.jsp.view;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
主类程序块
public final class transfer_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() {
}
主要服务逻辑代码,将需要展示的数据通过out对象write出各种html标签,展示一个静态的页面
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\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(" \r\n");
out.write("\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" \t<form action=\"");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath }", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null, false));
out.write("/transferservlet\"method=\"post\">\r\n");
out.write(" \t\t<table>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>转入账户</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"incount\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>转出账户</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"outcount\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td>交易金额</td>\r\n");
out.write(" \t\t\t\t<td><input type=\"text\" name=\"money\"/></td>\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t\t<tr>\r\n");
out.write(" \t\t\t\t<td colspan=\"2\" align=\"left\"><input type=\"submit\" value=\"确认交易\"/></td>\r\n");
out.write(" \t\t\t\t\r\n");
out.write(" \t\t\t</tr>\r\n");
out.write(" \t\t</table>\r\n");
out.write(" \t</form>\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 {
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);
}
}
}
JSP最佳实践,即MVC模式
在长期的实战中,人们得出如下习惯用法:
显示View:JSP适合做页面的显示,例如:显示登录成功界面
控制Controller:Servlet适合做业务控制操作,例如:接收用户请求,将用户请求的参数值封装到JavaBean对象中去,调用其它Java类处理,如果有结果,将结果放入到域对象中去,转发或重定向到显示结果的JSP页面
功能Model:Bean,即就是普通Java类,该类中封装大量的业务操作
JSP语法
JSP输出表达式
<%= ”xx” %>,主要用于向浏览器输出变量的值
注意:<%=和%>不可分隔,后面无分号JSP脚本片断
<% Java代码; %>
书写一行或多行Java代码,多个脚本片段可以相互访问,
注意:后面有分号,多个脚本片段之间可以相互调用JSP声明
<%! java代码 %>
JSP声明的变量或方法,会被翻译成Servlet的实例变量和成员方法JSP注释
- JSP中可以书写Java代码,所有Java代码的注释在JSP同样可以使用//
- JSP中可以书写HTML代码,所有HTML代码的注释在JSP同样可以使用
- JSP也有自已特有的注释,<%– xxxxxx –>,不能嵌套
- JSP引擎将 当作有效内容,翻译进Servlet源文件
- JSP引擎将<%– –%>当作无效内容,忽略,不翻译进Servlet源文件,推荐使用
JSP指令 ##
JSP指令是通知JSP引擎如何处理该JSP页面,总共三种指令:page指令、include指令、taglib指令
先扒一段头文件指令,再一一介绍。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
- page指令
<@page [ language="java" ] 默认java, 在JSP的脚本片段只能书写java代码 [import="{package.class|package.*},..] 默认java.lang,javax.servlet,javax.servlet.http,javax.servlet.jsp向jsp翻译后的servlet源码导入包
[ session="true | false" ] 默认true,true表示一旦访问jsp页面,自动创建HttpSession,false表示不自动创建HttpSession.
[ autoFlush="true | false" ] 默认true,jsp页面有缓存,在默认情况下,autoFlush=true表示缓存满后自动强行输出到浏览器,如果设置为false的话,得通过人工调用flush()方法才可以输出到浏览器
[ isThreadSafe="true | false" ] 默认true
jsp页面是否被多个线程同时访问安全?
如果设置为true,表示多个线程来访问jsp是安全的,如果设置为false的话,就表示该jsp页面在没有加锁的情况下,多个线程来访问,可能会出现安全问题
[ info="hello" ] 默认""表示给该jsp页面记录一些附加的信息
[ errorPage="relative_url" ] 无默认值,表示该jsp页面出错后,转发到指定的jsp页面进行错误消息的显示
/表示当前web应用的根目录,否则表示当前jsp页面 [ isErrorPage="true | false" ] 默认false
如果是用于错误消息的显示jsp页面,要加isErrorPage=true这个属性,这样jsp引擎就会创建exception内置对象,该exception内置对象中封装了出错的原因.如果设置为false的话,jsp引擎不会将exception内置对象翻译到servlet代码中,即无法在jsp页面中用exception对象来获取出错原因
- include指令
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/jsp/date.jsp"%>
<%@ include file="/jsp/el.jsp"%>
在一个JSP页面中包含多个其它的JSP页面 <%@ include file=”被包含的jsp页面的路径”%> 在翻译成Servlet时,就将被包含的JSP页面中的内容翻译成Servlet中了,即多个JSP只会翻译成1个Servlet
- taglib指令
在JSP页面中需要引用第三方的标签<%@ taglib uri=”名称空间” prefix=”标签的前缀”%>
JSP九大内置对象
由JSP引擎将JSP翻译成Servlet时,自动创建的对象,无需程序员创建的对象,直接使用即可,这些对象就叫内置对象。
- request : HttpServletRequest请求对象,请求域对象
- response: HttpServletResponse 响应对象
- session : HttpSession 会话域对象
- application : ServletcContext 应用域对象
- config : ServletConfig获取某个Servlet的初始化参数
- out : JspWriter(带缓冲的PrintWriter) JSP专用的字符输出对象
- exception: exception (特殊情况下用) 异常对象
- page: page this(本JSP页面) JSP页面自己
- pageContext: 当前域对象
pageContext功能强大,其中有一个findAttribute()这个API,它会依次从page->request->session->application这几个域对象,例如:
如果在request中找到了,就不会再去其它域对象中找了
如果在JSP中的上述四个域对象都没找到,返回null