您的位置:首页 > Web前端 > JavaScript

[转]Web安全之JSP详解

2015-11-02 18:05 393 查看

JSP中的脚本表达式

JSP脚本表达式(expression)用于将程序数据输出到客户端

语法:<%= 变量或表达式 %>

<%=new java.util.Date() %>


JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端。

JSP脚本表达式中的变量或表达式后面不能有分号(;)。

JSP中的脚本片段

JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码。语法:

<%
多行java代码
%>


注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。

JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。

在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。举例:

[html] view plaincopy在CODE上查看代码片派生到我的代码片

<%
int x = 10;
out.println(x);
%>
<p>这是JSP页面文本</p>
<%
int y = 20;
out.println(y);
%>


多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:

out.println(x);

单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例如:

<%
for (int i=1; i<5; i++)
{
%>
<H1>www.it315.org</H1>
<%
}
%>


Jsp的声明

JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面。语法:

<%!
java代码
%>


所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。

多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。

JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。

<%!
static
{
System.out.println("loading Servlet!");
}
private int globalVar = 0;
public void jspInit()
{
System.out.println("initializing jsp!");
}
%>


Jsp注释

JSP注释的格式:

<%-- 注释信息 --%>


JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。

Jsp指令

JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP2.0规范中共定义了三个指令:

page指令

Include指令

taglib指令

JSP指令的基本语法格式:

<%@ 指令 属性名="值" %>


首先我们来看一下page指令的用法

page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置。

JSP 2.0规范中定义的page指令的完整语法:

<%@ page
[ language="java" ]
[ extends="package.class" ]
[ import="{package.class | package.*}, ..." ]
[ session="true | false" ]
[ buffer="none | 8kb | sizekb" ]
[ autoFlush="true | false" ]
[ isThreadSafe="true | false" ]
[ info="text" ]
[ errorPage="relative_url" ]
[ isErrorPage="true | false" ]
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ]
[ pageEncoding="characterSet | ISO-8859-1" ]
[ isELIgnored="true | false" ]
%>


1.看一下通过page指令设置页面的编码:

举例:
<%@ page contentType="text/html;charset=gb2312"%>


这个指令的作用就相当于
response.setContentType("text/html;charset=gb2312");


2.通过page指令导入java包:

JSP 引擎自动导入下面的包:

java.lang.*
javax.servlet.*
javax.servlet.jsp.*
javax.servlet.http.*


可以在一条page指令的import属性中引入多个类或包,其中的每个包或类之间使用<%@ page import=”java.util.Date,java.sql.,java.io.“%>可以改写为使用多条page指令的import属性来分别引入各个包或类:

<%@ page import="java.util.Date"%>
<%@ page import="java.sql.*"%>
<%@ page import="java.io.*"%>


3.下面在来看一下buffer属性:

<%@ page buffer=”4kb” %>

使用这个属性是指定out对象的缓存大小

4.下面在来看一下isThreadSafe属性:

这个属性见名知意,是设置是否线程安全的,我们在之前讨论Servlet的时候,说到了Servlet是个单例对象,是线程不安全的,我们那时候可以通过实现一个接口来实现线程安全,这里只需要设置这个属性值就可以控制Jsp翻译之后的Servlet时候线程安全:

<%@ page isThreadSafe=”true|false” %> 默认值为true

isThreadSafe=false模式表示它是以Singleton模式运行。

该模式implements了接口SingleThreadMode,

该模式同一时刻只有一个实例,不会出现信息同步与否的概念。

若多个用户同时访问一个这种模式的页面,

那么先访问者完全执行完该页面后,后访问者才开始执行。

isThreadSafe=true模式表示它以多线程方式运行。

5.下面在来看一下session属性:

<%@ page session=”false|true”%> 默认值是true

是指不能在本页使用session.也就是在本页面禁用了session

就是在将Jsp翻译成Servlet的时候不会传递Session对象了.

6.下面来看一下errorPage属性

这个属性是设置服务器端出错之后的错误页面的,比如我们在编写服务器代码的时候,突然抛出异常,那么会返回一个500,这样给用户的感觉就很恶心,所以我们要做的人性化一点,就是通过这个属性值,设置一个错误页面,当服务器发生错误的时候都会跳转到这个页面中,比如:

<%@ page errorPage=”/error.jsp”%>

7.同时还有一个属性就是isErrorPages:

<@ page isErrorPages=”false|true”%> 默认值是true

是否开启错误页面,就是控制上面的errorPage属性的作用开关的

8.属性isELIgnored

<@ page isELIgnored=”false|true”%> 默认值是false

是否在该页面中忽视EL表达式的功能,这个我们一般都不去做设置,因为我们在页面中肯定会使用到EL表达式的

注意:如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。

Include指令

include指令很简单,就是实现页面包含的,通过代码来实现页面包含是动态包含,而使用include指令来实现页面包含是静态包含。

taglib指令

这个指令作用也是很简单的,就是引入标签

Jsp中内置的9个隐式对象

每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。

由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。

JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。

这9个对象分别是哪些,以及作用也是笔试经常考察的知识点。

request

response

config

application

exception

Session

page

out

pageContext

request:HttpServletRequest

response:HttpServletResponse

session: HttpSession

application: servletContext

config:servletConfig

out:JspWriter

exception

page:this

pageContext

上面其实很多对象我们都接触过了,之前介绍servlet的时候都介绍过了,关于那个exception是个异常对象,只有当我们的Jsp页面中抛出异常的时候,才会有这个对象的产生,否则是不会传递这个对象的,至于page对象,这个很简单就是当前对象,即jsp翻译后的servlet对象,那么下面就来详细解释一下out对象和pageContext对象了。

out隐式对象用于向客户端发送文本数据。

out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。

JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至可以关闭它的缓存。

只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:

1.设置page指令的buffer属性关闭了out对象的缓存功能

2.out对象的缓冲区已满

3.整个JSP页面结束

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象(之前我们介绍了三个域对象:ServletContext,Session,Request),这个域对象的生命周期最短,作用域最小,他的作用域就是当前的jsp页面,当然它可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。

getException方法返回exception隐式对象

getPage方法返回page隐式对象

getRequest方法返回request隐式对象

getResponse方法返回response隐式对象

getServletConfig方法返回config隐式对象

getServletContext方法返回application隐式对象

getSession方法返回session隐式对象

getOut方法返回out隐式对象

pageContext封装其它8大内置对象的意义,思考:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将具有什么功能?

这个我们在后面会介绍自定义标签的时候,这个用途就体现出来了,我们只需要传递一个pageContext对象,就可以操作其他多个对象了,很方便的

pageContext对象中的操作域中数据的方法

public void setAttribute(java.lang.String name,java.lang.Object value)

public java.lang.Object getAttribute(java.lang.String name)

public void removeAttribute(java.lang.String name)

pageContext对象中还封装了访问其它域的方法(和上面的方法不同之处就是多了一个参数,这个参数是可以直接指定相应的域)

public java.lang.Object getAttribute(java.lang.String name,int scope)

public void setAttribute(java.lang.String name, java.lang.Object value,int scope)

public void removeAttribute(java.lang.String name,int scope)

代表各个域的常量

PageContext.APPLICATION_SCOPE

PageContext.SESSION_SCOPE

PageContext.REQUEST_SCOPE

PageContext.PAGE_SCOPE

下面这个方法是非常重要的,因为这个方法是在所有的域中查找数据,查找顺序是:pageContext->request->session->ServletContext,如果查找不到相应的数据的话,就返回一个空字符串,这个方法和之后要说到的el表达式的功能是一样的

findAttribute方法 (*重点,查找各个域中的属性)

到此为止,web开发接触到了4个域对象:

pageContext(称之为page域)

request(称之为request域)

session(称之为session域)

servletContext(称之为application域)

这4个域对象是学习web的重点,也是笔试经常考察的知识点。

明确如下问题:

这4个对象的生命周期?

什么是域?为什么把这4个对象叫做域对象呢?

哪种情况下用哪种域对象。

PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法

传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相对于当前WEB应用程序的根目录,否则,表示相对于当前JSP所映射到的访问路径。

JSP标签库

虽然我们希望JSP页面仅用作数据显示模块,不要嵌套任何java代码引入任何业务逻辑,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面出现难看java代码,怎么办?

Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码。当然sun公司在jsp页面中也内置了一些标签(这些标签叫做jsp标签),开发人员使用这些标签可以完成页面的一些常用业务逻辑。

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能。

<jsp:include>标签
<jsp:forward>标签
<jsp:param>标签
<jsp:useBean>标签
<jsp:setProperty>标签
<jsp:getProperty>标签


1.标签

标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。

语法:

<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />


page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。

flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。

<jsp:include>
标签是动态引入(和使用代码进行include一样),
<jsp:include>
标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。 而include指令是静态引入(编译时引入),涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。不管是
<jsp:include>
标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。

例: 使用
<jsp:include>
标签来实现包含页面:

<jsp:include page="/head.jsp"></jsp:include>
<jsp:include page="/foot.jsp"></jsp:include>


会将head.jsp和foot.jsp单独翻译成servlet,这个就是动态包含。

使用include指令实现页面包含:

<%@ include file="/head.jsp" %>


并不会还单独翻译head.jsp页面了,因为是在代码中使用静态代码块实现静态页面包含的

2.标签

<jsp:forward>
标签用于把请求转发给另外一个资源。

语法:

<jsp:forward page="relativeURL | <%=expression%>" />


page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

3.或者标签

当使用和标签引入或将请求转发给其它资源时,可以使用标签向这个资源传递参数。

语法1:

<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>


语法2:

<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>


<jsp:param>
标签的name属性用于指定参数名,value属性用于指定参数值。在和
<jsp:forward>
标签中可以使用多个
<jsp:param>
标签来传递多个参数。

4.标签,标签,标签

这三个标签是一起用来操作bean对象的,
<jsp:useBean>
是用来初始化bean对象的,
<jsp:setProperty>
标签是用来设置bean对象中的属性值,
<jsp:getProperty>
标签是用来获取bean对象中的属性值的,例子:

<body>
<!-- 找到就直接用,找不到实例化 scope默认是page域-->
<jsp:useBean id="person" class="com.weijia.domain.Person" scope="page"/>

<!-- 直接设置属性值(8种基本类型的转换) -->
<jsp:setProperty name="person" property="name" value="xxx"/>

<!-- 用请求参数给属性赋值(8中基本类型的转换) -->
<jsp:setProperty name="person" property="name" param="name"/>

<!-- 获取Person中的属性name的值 -->
<jsp:getProperty name="person" property="name"/>
</body>


Jsp中怎么排查错误

JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

JSP页面翻译成的Servlet程序在运行时出现异常,这与普通Java程序的运行时错误完全一样,Java虚拟机将提示错误发生在Servlet源文件中的位(行和列)以及相关信息。

内容来源:

JavaWeb学习篇之—-Jsp详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: