📄 12. jsp note.txt
字号:
day1
JSP 定义:
1)Java Server Page, Java EE 组件,本质上是 Servlet。
2)运行在 Web Container.接收 Http Request,生成 Http Response(默认协议是 Http 请求和响应)
3)JSP 使得我们能够分离页面的静态 HTML 和动态部分——我们需要的技术。
4)使页面可以混和html代码、Java代码以及JSP标签;允许访问组件
Servlet的缺陷(JSP出现的原因):
1)写静态页面必须部署后才能看到效果,很难控制页面的外观。
2)从技术角度来说Servlet是Java代码和HTML静态代码的混合代码。
3)从市场竞争角度来说,微软推出了ASP产品。
JSP的改进:
1)JSP是标签式的文本文件(区Servlet是Java文件)
2)JSP不需要编译(其实是由服务器监测JSP文件的变化,再将其翻译成 Servlet 代码) 服务器对其进行编译并在第一次请求时创建一个Servlet实例。所以,第一次访问JSP页面时会后延迟
3)JSP不用写配置文件
4)JSP以静态代码为主,Java代码为辅。Servlet反之。
5)是J2EE蓝图的一部分(Servlet、JSP以及EJB是J2EE的三大组件)
JSP从本质上来说内核还是Servlet,但与Servlet不是替代关系而是一种互补的关系。
JSP适合于写显示层的动态页面,而Servlet则适合写控制层的业务控制(页面转发)。
JSP往纯标签方向发展,Servlet往纯代码方向发展,他们以Servlet内核(请求响应式的工作方式)往两个方向发展。
基本语法
一、JSP的声明(statement)
用来定义在产生的类文件中的类的属性和方法(成员变量)。可声明类(即是内部类)。 由于servlet是工作在多线程环境下,所以尽量不要在service方法体外声明成员变量。 <%!.....%> //声明时要加"!",属于类成员,最先加载,可写于任何位置;不加则是脚本的局部变量,必须调用前写。
如: <%!String hello="Hello, World!";%> //变量的声明
<%=hello%> //变量的调用
<%! private int counter=0; public int count(){ return ++counter;} %> //函数的声明
<h1><%=count()%></h1> //函数的调用 声明规则: 1) JSP中声明的变量和方法对应于Servlet中的实例方法和实例变量。这些将被同时请求该页面的所有用户所共享; 2) 在使用变量或方法前须先定义(不是说声明变量的位置在页面中要处于使用变量的前面,而是指变量不声明不能使用); 3) 声明的变量或方法的作用域为当前页面或包含的页面; 4) 语句间以分号分隔。
二、JSP代码段(Scriptlet)
<% java代码 %>
是一段可以在处理请求时间执行的Java代码。可以产生输出,也可以是一些流程控制语句。 在代码段中定义的变量为service方法中的局部变量。 1._jspService()中的局部代码:
<% System.out.println("Hi,I like JSP."); %> //在控制台打印出,网页上没显示
<% out.println("Hi,I like JSP."); %> //打印在网页上
<% Connection conn=DriverManager.getConnection(); Statement st=conn.createStatement();
String sql="select * from users"; ResultSet rs=st.executeQuery(sql);
//……
%>
问:能否在JSP脚本里定义方法?
答:不能! //脚本相当于方法,不能在方法里定义方法
<%!public void helloworld(){}%> //可以声明方法
<% public void helloworld(){}%> //编译出错;脚本不能定义方法
2.比较:
<%! int i=100;%> //成员变量
<% int i=101;%> //_jspService()方法中的局部变量
<%=i%> //同一文件里,局部变量优先 3.脚本小程序规则: 1) 你使用的脚本语言决定了脚本小程序的规则; 2) 语句间以分号分隔; 3) 可以使用默认的对象、import进的类、declaration声明的方法和对象以及useBean tag中声明的对象。
三、JSP表达式(expression)
<%=……%> // "="号
在JSP请求处理阶段计算他的值,表达式生成的代码是Service方法中的一个代码片断。 JSP对于声明的处理:1、计算表达式的值
2、将值转换成String
3、用out.println发送标签;把数据输出至页面的当前位置
<%="Hello,JSP world!"%> //out.println("Hello,JSP world");
<%=name%> //<%!String name="GiGi";%> out.println(name);
<%=new java.util.Date()%> //out.println(new java.util.Date()); 表达式规则: 1) 你使用的脚本语言决定了脚本小程序的规则; 2) 执行的顺序为从左到右; 3) 分号不能用于表达式。
四、JSP指令(direction)
指令用于从JSP发送信息到容器上。用来设置全局变量,声明类,要实现的方法和输出内容等。
指令在JSP整个文件内有效。它为翻译阶段提供了全局信息。
<%@......%> // "@"符号
指令包括:page、include、taglib
1.page指令
import、session、errorPage、isThreadSafe
页面的语言、内容类型、字符集、页面编码
<%@page language="java" contentType="text/html; charset=gbk" pageEncoding="gbk"%>
language:java唯一值,表示脚本中使用的编程语言
contentType:设置了内容的类型和静态页面的编码 (告诉浏览器以什么编码显示)
pageEncoding:页面本身的编码格式 (写页面时用的编码格式)
上面的代码等价于servlet里: response.setContentType("text/html; charset=gbk");
import:导入其他的包和类; 其中,JSP默认导入的包是java.lang.*
<%@page import="java.util.Date"%> //具体的包和类
<%@page import="java.sql.*"%> //包下的所有类
<%@page import="java.util.*, java.io.*, java.net.*"%> //连写,逗号分隔
Session:指示当前的jsp是否参与会话 (默认为true; 参与会话)
通过指令使当前页面与session不可会话: <%@page session="false"%>
session="true"时,可用内建对象session直接访问会话,例如:
<% session.setAttribute("username","maxwell");
String name = (String)session.getAttribute("username"); %>
<%=name%>
errorPage:
isErrorPage:Jsp页面中出现异常的处理方式
对于有可能出现异常的页面:
<%@page errorPage="error.jsp"%> //异常时会跳转到处理异常的页面;这页面自己写
在有可能异常的地方打印原因: throw new Exception("数据库连接出错");
对于处理异常的页面(error.jsp)里:
<%@page isErrorPage="true"%>,其中使用<%=exception.getMessage() %>把异常信息打印出来
isThreadSafe——此属性已经不再使用(已废弃)
当前Jsp页面是否线程安全 default--->true
<%@page isThreadSafe="true"%> //普通的Servlet,可以并发处理用户请求
<%@page isThreadSafe="false"%> //相当于Servlet实现了SingleThreadModel
2.include指令
把目标页面的内容包含到当前页面,产生页面叠加以后的输出效果 //相当于将两个页面合并;编译时就包含进来
<%@include file="foot.jsp"%> //可插入任意位置
3.taglib指令
留在JSTL里讲解。
五、JSP中的注释
1.java格式注释
编译器会忽略掉此类注释中的内容(客户端的源码看不见)
<%-- JSP注释;可多行 --%>
<%// java 单行注释 %>
<%/* java multi lines comments */%>
<%/**java 特有的注释*/%>
2.html风格注释
编译器会执行此类注释中的代码(客户端的源码看得见)
<!-- html风格注释 --> 等价于out.println("<!-- html风格注释 -->")
这种注释方式不好的地方就是当页面注释信息太多的时候会增大服务器的负荷。
还有注释信息需要在网络上传输,从而降低效率;内部程序员的测试数据一般不能写在这种注释中,以免泄露。六、动作(Action)
<jsp:actionName attributeName=attributeValue/>
JSP的动作包括:
forward、include、useBean、setProperty、getProperty
1.forward动作
形式:<jsp:forward page="another.jsp"/>
等价于 Servlet中通过RequestDispatcher.forward();
可以传参数
<jsp:forward page="another.jsp">
<jsp:param name="name" value="maxwell"/>
<jsp:param name="age" value="20" />
</jsp:forward>
2.Include动作
形式:<jsp:include page="another.jsp"/>
等价于 Servlet中通过RequestDispatcher.include();
Include动作也可以传参数
<jsp:include page="b.jsp" flush="true">
<jsp:param name="name" value="narci"/>
</jsp:include>
与<%@include file=""%>比较:
include动作在运行期处理(include指令编译期),jsp:include包含的是所包含URI的响应,而不是URI本身。
这意味着:jsp:include 对所指出的 URI 进行解释,因而包含的是生成的响应。
对于页面是静态内容,这没有太大的关系。但如果是动态内容,include动作可传参数。
flush 属性
flush 指示在读入包含内容之前是否清空任何现有的缓冲区。
JSP 1.1 中需要 flush 属性,因此,如果代码中不用它,会得到一个错误。
但是,在 JSP 1.2 中, flush 属性缺省为 false。
建议:由于清空大多数时候不是一个重要的问题,因此,对于 JSP 1.1,将 flush 设置为 true;
而对于 JSP 1.2 及更高版本,将其设置为 false 或不设置(用默认值)。
JSP的生命周期
1) 每一个JSP都会对应有一个servlet生成 2) 在 %tomcat%/work/Catalina/localhost/工程名/org/apache/jsp 目录下可找到对应生成的 Servlet 文件 3) 一般而言,每一个JSP对应的servlet都有如下的生命周期方法:
一、 _jspInit()方法
JSP容器第一次装载jsp文件时调用一次
public void _jspInit(){……}
二、 _jspService()方法
每当服务器接收到对该jsp的请求,都需要调用一次该方法一次。
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { ……}
三、 _jspDestroy()方法
jsp文件被修改时,JSP容器会销毁旧的jsp文件对应的对象,重新装载一次更新后的jsp文件的内容(只调用一次)。
public void _jspDestroy(){……}
JSP处理过程:JSP源文件处理分成二个阶段:
1) JSP页面转换阶段: 页面被编译成一个Java类,所有的HTML标记和JSP标记都被转换创建一个Servlet。这时,脚本和表达式还没有被执行;
2) 请求处理阶段:发生在服务器,将一个客户端请求指向JSP页面。 一个请求对象创建、解析以及提交给编译好的JSP对应的servlet。 当这个servlet处理请求的时候它执行先前在JSP中定义的处理脚本小程序和表达式。
使用脚本代码的缺点和指导方针
1) 缺点: a. 过度使用脚本代码使用JSP页面混乱和难以维护; b. 脚本代码降低JSP二个主要的优点:软件重用和代码分开
2) 指导方针:只在组件功能无能为力或需要有限的脚本时使用。
day2
POJO: Plain Old Java Object --> 简单传统的Java对象
Java Bean: 组件、构件的规范(属性,提供get/set方法;还可包含其他方法)
JSP调用JavaBean
通过引入JavaBean,JSP才能较好的把页面展示与业务逻辑分离。
其中,业务逻辑放到后台的Java Bean中,减少JSP中的脚本代码,有利于程序的可维护性与可重用性。
一、Java Bean
a.无参构造器(也是默认的构造方法)
b.标准的getter、setter方法
c.如要进行网络传输(支持RMI),需实现Serializable接口
二、如何在JSP中使用JavaBean?
1.定义Java Bean
形式:<jsp:useBean id = "BeanName" class = "className" sope="范围域">
id ——声明bean对象的标识符,方便其他地方使用
class——bean对象的类型,注意要使用完全限定名
scope——java bean对象的共享范围(page、request、session、application)
page:当前页面范围(范围最小,生命周期最短)
request:同一个请求范围 (forward,include)
session:同一个会话(30分钟不使用,会自动结束)
application:同一个应用(范围最大,生命周期最长) ServletContext
例如: SuperGirl <jsp:useBean id="girl" class="com.tarena.vo.SuperGirl" scope="session"/>
等价于:<% SuperGirl girl=(SuperGirl)session.getAttribute("girl");
if(girl==null){
girl = new SuperGirl(); //对应 id 和 class
session.setAttribute("girl",girl); //对应 scope 的值
} %>
可以用表达式获得bean的值: <%=girl.getName();%>
2.对JavaBean的属性赋值
形式:<jsp:setProperty name="JavaBean对象名" property="JavaBean属性名" value="属性值"/>
例子: <jsp:setProperty name="girl" property="name" value="Lily"/>
等价于: <% girl.setName("Lily");%>
可以嵌套JSP表达式:
<jsp:setProperty name="girl" property="name"
value='<%=request.getParameter("name")%>'/>
Java Bean中的属性名与form中输入域的名字保持一致的话,可以使用通配符*,一次设置所有字段的值。
<jsp:setProperty name="" property="*"/>
3.获取JavaBean的属性值
形式:<jsp:getProperty name="" property=""/>
name:标识具体的Bean对象,这与<jsp:useBean>标准动作中的id值相匹配
property:标识属性中的标识符。
JSP中的异常处理
一、try/catch/finally/throws/throw
// 在局部代码里处理异常。
二、errorPage, isErrorPage
// 在整个页面处理异常。
1.errorPage
形如: <%@page errorPage="error.jsp"%>
表示:需要错误处理的页面
2.isErrorPage
形如: <%@page isErrorPage="true"%>
指示:错误页面。其中,有一个隐式对象exception可用: <%=exception%>
产生(隐含)内建对象exception,可通过它获得异常信息 <%=exception.getMessage() %> //把异常信息打印出来
三、声明的方式处理异常
// 在整个应用处理异常。(范围比前两种更大)
1.配置: 在web.xml进行配置异常处理
…… <error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/MathError.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page> ……
2.复习:Java中的异常——有2种
受查异常(Checked Exception)
非受查异常(Unchecked Exception) Java中的RuntimeException及其子类是不需要处理的(try/catch)
因为所有的RuntimeException总是可以通过优化代码来避免,因此,这种异常被称为"Unchecked Exception"。
3.思考:
三种异常处理方式同时启动用,那个优先级高? 作用域越小,优先级越高。
注意:要使得页面自动跳转到错误页面,必须关闭浏览器的"显示友好HTTP错误信息"选项。
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { /*只处理这两种兼容的异常*/ …… }
安全的系统(企业级应用):
1.身份认证(合法用户) --登录
2.授权(静态) --定义权限
3.访问控制(动态) --比较
4.安全审计(日志) --修复bug (只有敏感的部门需要)
JAAS实现安全
JAAS——Java Authentication and Authorization Service
(Java认证(Authentication)与授权(Authorization)服务) 是Java EE规范之一,实现Java EE应用程序安全性的一个重要途径
(要求:会使用,不必深入理解)
一、网络安全的4大要素
认证——抵御假冒者(用户身份的合法性)
授权——合法用户拥有的权限
机密性——防止关键数据落入其他人手中
数据完整性——抵御窃听者(篡改私有数据)
二、对于Http应用是如何进行认证的(Web端的认证方法)?
四种安全认证: (http协议)basic, form, digest, certificate(证书) + ssl
HttpMonitor监控受限资源的访问
三、容器是如何完成认证与授权的呢?
图示(容器做了些什么事情)
(容器的角度)
四、声明式安全以及分工
Servlet的开发者
应用的管理员
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -