阅读前提:了解Tomcat服务器和Servlet
在web开发中我们可以通过Servlet的Response对象对浏览器输出我们的网页内容
这样虽然可以进行网页输出,但是代码编写极其繁杂,冗余很多,所以jsp就出现了;
先描述一下现象,首先我们可以在myeclipse新建Manager的web project,在WebRoot下会有index.jsp文件;
1 <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 This is my JSP page. <br> 25 </body> 26 </html>
开启服务器后我们可以在浏览器访问localhost:8080/mg/index.jsp(mg是我的虚拟项目名)
浏览器页面为:
原理:根据上面的描述似乎我们可以通过 "/项目虚拟名/jsp文件路径" 的方式来访问我们的jsp文件。其实并不是的,我们访问的根本不是我们项目截图看到的index.jsp。
在我们的Tomcat服务器的conf文件夹下的web.xml文件中,有这样几句代码:
所以对于我们浏览器请求中所有的以 .jsp 结尾的请求其实真实访问的都是org.apache.jasper.servlet.JspServlet这个Servlet,那这个Servelt拿到请求后干了什么事情呢?其实主要的就是找到请求的index.jsp文件,将这个jsp文件转译成一个Servlet,并请求给这个Servlet进行处理。
如何转译:1,将所有html语句转成上面第一张图那样的write语句输出。2,保留jsp原有的java代码。
1 /* 2 * Generated by the Jasper component of Apache Tomcat 3 * Version: Apache Tomcat/7.0.56 4 * Generated at: 2019-08-03 06:25:27 UTC 5 * Note: The last modified time of this file was set to 6 * the last modified time of the source file after 7 * generation to assist with modification tracking. 8 */ 9 package org.apache.jsp; 10 11 import javax.servlet.*; 12 import javax.servlet.http.*; 13 import javax.servlet.jsp.*; 14 import java.util.*; 15 16 public final class Login_jsp extends org.apache.jasper.runtime.HttpJspBase 17 implements org.apache.jasper.runtime.JspSourceDependent { 18 19 private static final javax.servlet.jsp.JspFactory _jspxFactory = 20 javax.servlet.jsp.JspFactory.getDefaultFactory(); 21 22 private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; 23 24 private javax.el.ExpressionFactory _el_expressionfactory; 25 private org.apache.tomcat.InstanceManager _jsp_instancemanager; 26 27 public java.util.Map<java.lang.String,java.lang.Long> getDependants() { 28 return _jspx_dependants; 29 } 30 31 public void _jspInit() { 32 _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 33 _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 34 } 35 36 public void _jspDestroy() { 37 } 38 39 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 40 throws java.io.IOException, javax.servlet.ServletException { 41 42 final javax.servlet.jsp.PageContext pageContext; 43 javax.servlet.http.HttpSession session = null; 44 final javax.servlet.ServletContext application; 45 final javax.servlet.ServletConfig config; 46 javax.servlet.jsp.JspWriter out = null; 47 final java.lang.Object page = this; 48 javax.servlet.jsp.JspWriter _jspx_out = null; 49 javax.servlet.jsp.PageContext _jspx_page_context = null; 50 51 52 try { 53 response.setContentType("text/html;charset=utf-8"); 54 pageContext = _jspxFactory.getPageContext(this, request, response, 55 null, true, 8192, true); 56 _jspx_page_context = pageContext; 57 application = pageContext.getServletContext(); 58 config = pageContext.getServletConfig(); 59 session = pageContext.getSession(); 60 out = pageContext.getOut(); 61 _jspx_out = out; 62 63 out.write(' '); 64 out.write(' '); 65 66 String path = request.getContextPath(); 67 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 68 69 out.write(" "); 70 out.write(" "); 71 out.write("<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "); 72 out.write("<html xmlns="http://www.w3.org/1999/xhtml"> "); 73 out.write("<head> "); 74 out.write(" <base href=""); 75 out.print(basePath); 76 out.write(""> "); 77 out.write("<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> "); 78 out.write("<title>欢迎登录后台管理系统</title> "); 79 out.write("<link href="css/style.css" rel="stylesheet" type="text/css" /> "); 80 out.write("<script language="JavaScript" src="js/jquery.js"></script> "); 81 out.write("<script src="js/cloud.js" type="text/javascript"></script> "); 82 out.write(" "); 83 out.write("<script language="javascript"> "); 84 out.write(" $(function(){ "); 85 out.write(" $('.loginbox').css({'position':'absolute','left':($(window).width()-692)/2}); "); 86 out.write(" $(window).resize(function(){ "); 87 out.write(" $('.loginbox').css({'position':'absolute','left':($(window).width()-692)/2}); "); 88 out.write(" }) "); 89 out.write("}); "); 90 out.write("</script> "); 91 out.write(" "); 92 out.write("</head> "); 93 out.write(" "); 94 out.write("<body style="background-color:#df7611; background-image:url(images/light.png); background-repeat:no-repeat; background-position:center top; overflow:hidden;"> "); 95 out.write(" "); 96 out.write(" "); 97 out.write(" "); 98 out.write(" <div id="mainBody"> "); 99 out.write(" <div id="cloud1" class="cloud"></div> "); 100 out.write(" <div id="cloud2" class="cloud"></div> "); 101 out.write(" </div> "); 102 out.write(" "); 103 out.write(" "); 104 out.write("<div class="logintop"> "); 105 out.write(" <span>欢迎登录后台管理界面平台</span> "); 106 out.write(" </div> "); 107 out.write(" "); 108 out.write(" <div class="loginbody"> "); 109 out.write(" "); 110 out.write(" <span class="systemlogo"></span> "); 111 out.write(" <br /> "); 112 out.write(" "); 113 114 Object obj=request.getAttribute("flag"); 115 if(obj!=null){ 116 117 out.write(" "); 118 out.write(" <div style="text-align:center;"> "); 119 out.write(" <span style="font-size:15px;color:darkred;font-weight:bold;">用户名或密码错误</span> "); 120 out.write(" </div> "); 121 out.write(" "); 122 } 123 out.write(" "); 124 out.write(" "); 125 out.write(" "); 126 127 Object pwd=session.getAttribute("pwd"); 128 if(pwd!=null){ 129 130 out.write(" "); 131 out.write(" <div style="text-align:center;"> "); 132 out.write(" <span style="font-size:15px;color:darkred;font-weight:bold;">密码修改成功</span> "); 133 out.write(" </div> "); 134 out.write(" "); 135 } 136 session.removeAttribute("pwd"); 137 138 out.write(" "); 139 out.write(" "); 140 out.write(" "); 141 out.write(" "); 142 143 Object reg=session.getAttribute("reg"); 144 if(reg!=null){ 145 146 out.write(" "); 147 out.write(" <div style="text-align:center;"> "); 148 out.write(" <span style="font-size:15px;color:darkred;font-weight:bold;">注册成功</span> "); 149 out.write(" </div> "); 150 out.write(" "); 151 } 152 session.removeAttribute("pwd"); 153 154 out.write(" "); 155 out.write(" <div class="loginbox loginbox2"> "); 156 out.write(" <form action="user" method="post"> "); 157 out.write(" <input name="oper" type="hidden" value="login"/> "); 158 out.write(" <ul> "); 159 out.write(" <li><input name="uname" type="text" class="loginuser" placeholder="用户名"/></li> "); 160 out.write(" <li><input name="pwd" type="password" class="loginpwd" placeholder="密码"/></li> "); 161 out.write(" <li class="yzm"> "); 162 out.write(" <span><input name="" type="text" placeholder="验证码"/></span><cite>X3D5S</cite> "); 163 out.write(" </li> "); 164 out.write(" <li><input name="" type="submit" class="loginbtn" value="登录" /><label><a href="/mg/user/reg.jsp">注册</a></label><label><a href="#">忘记密码?</a></label></li> "); 165 out.write(" </ul> "); 166 out.write(" </form> "); 167 out.write(" "); 168 out.write(" </div> "); 169 out.write(" "); 170 out.write(" </div> "); 171 out.write(" "); 172 out.write(" "); 173 out.write(" <div class="loginbm">版权所有 ZDL <a href="http://www.uimaker.com">uimaker.com</a> 仅供学习交流,勿用于任何商业用途</div> "); 174 out.write(" "); 175 out.write(" "); 176 out.write("</body> "); 177 out.write(" "); 178 out.write("</html> "); 179 } catch (java.lang.Throwable t) { 180 if (!(t instanceof javax.servlet.jsp.SkipPageException)){ 181 out = _jspx_out; 182 if (out != null && out.getBufferSize() != 0) 183 try { 184 if (response.isCommitted()) { 185 out.flush(); 186 } else { 187 out.clearBuffer(); 188 } 189 } catch (java.io.IOException e) {} 190 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); 191 else throw new ServletException(t); 192 } 193 } finally { 194 _jspxFactory.releasePageContext(_jspx_page_context); 195 } 196 } 197 }
为什么不直接转译html文件?因为html代码都是写死的,但jsp文件可以写java代码保留到Servlet中执行,可以做逻辑判断,循环输出,获取Session数据等,保留了Servlet编程的灵活性。
下面开始介绍jsp的使用方法:
1,page指令:配置jsp转成的Servlet的一些参数,还有一些Response对象的参数;
格式:<%@page 属性名="属性值" 属性名="属性值"...%>
属性: language:声明jsp要被转译的语言。
import:声明转译的java文件要导入的包,不同的包使用逗号隔开。
pageEncoding:设置jsp文件的数据编码格式。
contentType="text/html; charset=utf-8" 设置jsp数据响应给浏览器时,浏览器的解析和编码格式。
session:设置转译的servlet中是否开启session支持,默认开启,true表示开启。false表示关闭。
errorPage:设置jsp运行错误跳转的页面.
extends:设置jsp转译的java文件要继承的父类(包名+类名)。
2,局部代码块:会原样转换到转译的Servlet的Service方法中(其实是_JspService方法,但只是换个名字,作用都一样,就当做Servlet方法来理解就好了)
格式:<% java代码%>
<% int a=2; if(a>3){ %> <b>jsp学习很简单</b> <%}%>
就上面的代码中只有当a大于3时,<b>jsp学习很简单</b>才会输出到客户端,所以可以做逻辑判断了,输出的html不再是程序员写死的了。但是上面的代码很显然有书写麻烦,阅读困难的缺点。
3,全局代码块:区别于局部代码块写到service方法体中,全局代码块是写到Servlet类中,方法体外,作为全局变量,在程序的一开始就执行;
格式:<%!全局代码%>
4,脚本段语句:帮助我们快速的获取变量或者方法的返回值作为数据响应给浏览器。
格式:<%=变量名或者方法%>
其实<%=str%>就相当于<%out.write(str);%>
注意:不要在变量名或者方法后使用分号。
5,静态引入:会将引入的jsp文件和当前jsp文件转译成一个java(Servlet)文件使用
格式:<%@include file="要引入的jsp文件的路径" %>
注意:1,静态引入的jsp文化不会单独转译成java(Servlet)文件。因为两个jsp会被了一个Servlet,但采用的是主动引用的jsp的名字命名Servelt;2,当前文件和静态引入的jsp文件中不能够使用java代码块声明同名变量。
6,动态引入:会将引入的jsp文件单独转译,在当前文件转译好的java文件中调用引入的jsp文件的转译文件。在网页中显示合并后的显示效果。
格式:<jsp:include page="要引入的jsp文件的路径"></jsp:include>
注意:动态引入允许文件中声明同名变量。
7,转发标签forward:转到别的jsp
格式:<jsp:forward page="要转发的jsp文件的路径"></jsp:forward>
特点:一次请求,地址栏信息不改变。
注意:在转发标签的两个标签中间除了写<jsp:param name="str" value="aaa" />子标签不会报错,其他任意字符都会报错。
<jsp:param name="str" value="aaa" />
name属性为附带的数据的键名
value为附带的数据内容
name和value会将数据以?的形式拼接在转发路径的后面。
8,jsp的九大内置对象:
内置对象:jsp文件在转译成其对应的Servlet文件的时候自动生成的并声明的对象。我们在jsp页面中直接使用即可。
注意:内置对象在jsp页面中使用,使用局部代码块或者脚本段语句来使用。不能够在全局代码块中使用。
内容:九个对象(其实基本跟Servlet的对象差不多)
pageContext:页面上下文对象,封存了其他内置对象。封存了当前jsp的运行信息。
注意:每个Jsp文件单独拥有一个pageContext对象。
作用域:当前页面。
request:封存当前请求数据的对象。
session:此对象用来存储用户的不同请求的共享数据的。
application:也就是ServletContext对象,一个项目只有一个。存储用户共享数据的对象,以及完成其他操作。
response:响应对象,用来响应请求处理结果给浏览器的对象。设置响应头,重定向。
out:响应对象,Jsp内部使用。带有缓冲区的响应对象,效率高于response对象。
page:代表当前Jsp的对象。相当于java中的this。
exception:异常对象。存储了当前运行的异常信息。
注意:使用此对象需要在page指定中使用属性isErrorPage="true"开启。
config:也就是ServletConfig,主要是用来获取web.xml中的配置数据,完成一些初始化数据的读取。
9,Jsp的路径
使用相对路径,但是资源的位置不可随意更改,要更改会比较麻烦;
使用绝对路径:
/虚拟项目名/项目资源路径
注意:在jsp中资源的第一个/表示的是服务器根目录,相当于:localhost:8080
jsp中自带的全局路径声明:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath%>">
作用:给资源前面添加项目路径,相当于: http://127.0.0.1:8080/虚拟项目名/