07 jsp技术

一、 jsp入门

java server page

1. web资源的运行原理

    html: 静态web资源,DefaultServlet读取html文件,通过response输出给IE浏览器

    Servlet: 动态web资源,web容器(Servlet引擎)解析web.xml文件,找到url对应的java类

              通过反射创建Servlet对象,调用service方法

              Class.forName(“cn.itcast.servlet.Servlet1”).newInstance();

    jsp:动态web资源

    jsp页面在第一次被访问的时候,web容器(jsp引擎)会将jsp翻译成一个Servlet,然后调用servlet的

       service方法

    jsp翻译后的Servlet会被放到

    %tomcat安装目录%\work\Catalina\localhost\webcontext

    当jsp页面被再次访问的时候,web容器会去直接调用Servlet的 service方法,所以通常来讲 jsp 只是在第一次被访问的时候比较慢

    如果jsp页面做了修改,此时web容器会重新翻译jsp

 

2. jsp 是什么

实际上 jsp 就是 Servlet , 只是提供了一种比较直观的书写方式,因为写jsp就像在写Html

 

jsp中可以写 java 代码, 有两种写法

1) jsp 脚本表达式

内容会被放到 out.print()里面 输出个浏览器

<%=new Date() %>

 

2) jsp脚本片段

内容会原封不动地被翻译到Servlet 的service方法中

<%

    //java 代码

   

%>

 

3. jsp 和Servlet的区别

1) Servlet 适合写java代码,因为Servlet就是一个java类

    在开发中使用Servlet对用户发送的请求进行处理并做出响应

   

2) jsp 适合做数据美化,作为数据显示模板

    因为jsp页面直接书写HTML标签

 

3) 项目中的web层通常使用mvc设计模式 Servlet+jsp+javabean

    其中, Servlet做控制器,处理用户请求

           jsp作为显示模板

           javabean作为封装数据的实体

 

4) 如何养成一种良好的编码风格

    在Servlet中应避免做任何的数据输出

    在 jsp 中应避免去直接书写java代码, 而实际上要做到这点很难, 所以需要用到 el 和 jstl

    (jsp中必须要写的java代码,从域对象中取出数据)

 

二、 jsp语法

1. 模板元素

    在 jsp 页面中所有的 html 标签部分被称作模板元素,用于对整个网页进行布局

2. jsp脚本

    jsp中的java代码被称作jsp脚本

    有三种形式

    1)脚本表达式

       被翻译到 out.print() 方法中

       <%=newDate() %>

    2)脚本片段

       被翻译到 service 方法中

       <%

           for(inti=0; i<10; i++) {

              System.out.println(i);

           }

       %> 

    3)jsp 声明

       被翻译到 service 方法外面

       写成员变量\成员方法\静态代码块

       <%!

           privateString name;

           static{

              .......

           }

       %>

 

 

3. jsp指令

include指令

作用:把2个页面的输出合并。

    属性:file:要合并的页面的路径。路径如果以"/"表示绝对路径。

taglib 指令

    作用:引入外部的标签

    属性:uri:外部标签所在的名称空间

         prefix:前缀

    比如:<%@ tagliburi="http://java.sun.com/jsp/jstl/core" prefix="c"%> 

page指令用于向jsp引擎说明jsp的页面情况

page指令一般都放在页面的开头,但是不管放在哪都对整个页面起作用

page指令常用的主要有一下几个:

  language:指示JSP中使用的脚本语言。默认为java,目前支持java。

  extends:指示JSP对应的Servlet的爸爸。请不要修改。

  *import:导入JSP中的Java脚本中使用到的java包或类。

           作用等同java类中的import

           JSP引擎会自动引入以下包:

              javax.servlet.*

              javax.servlet.http.*

              javax.servlet.jsp.*(JSP规范类所在的包)

  *session:JSP页面中是否生成HttpSession对象。

           默认值true。可选值true|false

  buffer:JSP输出流JspWriter的缓存。默认值8Kb

           可选值:none|your sizeKb

  autoFlush:JSP输出流缓存满了,自动刷新

  isThreadSafe:默认值是true。可选值true|false。

           指示JSP对应的Servlet是否实现SingleThreadModel

           取值为false时才会实现该接口

  *errorPage:指示当前JSP页面出错后,转向的页面。服务器转发技术。路径如果以"/"表示绝对路径。

   

    配置全局错误提示页面:(不是服务器转发技术)

       web.xml

       <error-page>

           <exception-type>java.lang.Exception</exception-type>

           <location>/error.jsp</location>

        </error-page>

        <error-page>

           <error-code>404</error-code>

           <location>/404.jsp</location>

        </error-page>

  *isErrorPage:指示页面中是否生成exception对象。

           默认值false。

  *contentType:指示JSP其余内容的MIME类型。等同response.setContentType

              text/html;charset=UTF-8.

  * pagaEncoding

    通知jsp引擎在翻译jsp的过程中以什么编码方式来解码jsp文件

    通知 Servlet引擎 response编码方式,相当于 response.setContentType()

    说白了只要给jsp指定了 pageEncoding=”utf-8”

    jsp引擎在翻译jsp时, 就会自动加上一句

    response.setContentType(“text/html;charset=utf-8”)

   

    其他功能:page可以没有contentType,只有pageEncoding等同于contentType+pageEncoding

  *isELIgnored:指示是否忽略EL表达式。

              默认值false,不忽略

              如果为true,忽略表达式,即把表达式当做普通HTML文本对待。

 

扩展 : jsp 乱码问题

在 tomcat6 以后jsp就没有乱码问题了, 如果是使用tomcat5 才会出现乱码问题

jsp 乱码解决  告诉jsp引擎jsp页面是什么码,这样翻译才不会错

告诉response用什么码编码再发给浏览器

 

三、 jsp 九个隐式对象 (笔试)

1. 面试题:

列举出jsp页面的九个隐式对象,并加以说明

 

对象变量名,可直接在jsp中使用

对象类型

config

ServletConfig

application

ServletContext

response

HttpServletResponse

request

HttpServletRequest

session

HttpSession

out

JspWriter

page

this(当前servlet对象)

exception

Throwable

pageContext

PageContext

注意:

exception对象不是每个页面都有 只有是错误页面(errorPage),并且isErrorPage属性设置为true

session 对象也不是每个页面都有  默认情况下有,但是如果将page指令的 session=”false”,则没有session内置对象

 

2. out 对象

JspWriter类型, 带缓冲的字符流 (包装流) BufferedWriter

写入该流的数据最终会被刷新到 response ,调用response.getWriter().write(buffer)方法

 

什么情况下 JspWriter 会将数据刷新

1) 缓冲区写满(默认大小为8kb, 可以在page指令中通过 buffer属性设置缓冲区大小)

2) jsp 页面结束

 

注意:

1)jsp中输出数据尽量使用 out 不要使用response直接获得流输出

原因在于, 写入 out 的数据会进缓冲区再刷新到response, 如果两个都用,会导致后写的数据显示在前面

2)jsp 页面结束时会自动调用 response.getWriter() 将数据刷新

所以在jsp中不要调用 getOutputStream()

当然也不方便做文件下载

 

结论: 在jsp中用out输出数据

 

3. pageContext对象

主要功能,用于获得其他8大隐式对象

这样做的意义:

需要移除jsp中的java代码,就需要将java代码写到一个java类的成员方法中,然后想办法在jsp

页面中调用该方法,以达到代码复用的目的

由于在jsp中的java代码难免会访问8个隐式对象,因为这些对象都是和web开发相关的对象

要移除这部分java代码就需要将8个对象传递给java类的方法,为了方便,我们通常的做法是只传递一个

pageContext对象过去,这样在方法中就可以通过该对象很轻松地获得其他8个对象了

 

pageContext 也是一个域对象,但只是在当前jsp页面有效

 

重点:

1)  默写9个对象, (具体描述9个对象怎么用)

2)  理解pageContext对象的意义 (获得其他8个对象)

 

pageContext 有个特殊的方法 findAttribute()

 

四、 web开发中的四个域(重点)

范围由小到大: page(jsp有效) request(一次请求)session(一次会话) application(当前web应用)

page : PageContext对象,PageContext(Servlet代码基本不用)

request : HttpServletRequest对象,ServletRequest保持数据必须在转发的一瞬间,数据一次性的。

session : HttpSession对象,HttpSession一次会话过程中都需要用得到的数据,比如登陆信息,购物信息。

application : ServletContext对象,应用级别的,同步。

 

class Request {

    privateMap<String, Object> attributes = new HashMap();

 

    publicvoid setAttribute(String name, Object value) {

       attributes.put(name,value);

}

 

public ObjectgetAttribute(String name) {

    return attributes.get(name);

}

 

public voidremoveAttribute(String name) {

    attributes.remove(name);

}

}

 

1. 这4个对象的生命周期?

生命周期就是指对象的创建到销毁的期间

page: jsp 页面被执行,生命周期开始,jsp 页面执行完毕 ,生命周期结束

request : 用户发送一个请求,开始,服务器返回响应,请求结束,生命周期结束

session : 用户打开浏览器访问,创建session(开始),session超时或被声明失效,该对象生命周期结束

application: web应用加载的时候创建(开始), web应用被移除或服务器关闭,对象销毁(结束)

 

2. 四个域的作用范围

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

域:即范围的意思

web中的域对象,可以存储对象,在作用范围内都可以取到

内部是Map集合的实现Map<String, Object>

 

classPageContext {

private Map attributes = new HashMap();

private HttpSession session;

……

 

public void setAttribute(String name, Object value) {

         attributes.put(name,value);

}

 

public Object getAttribute(String name) {

         attributes.get(name);

}

public void removeAttribute(String name) {

         attributes.remove(name);

}

}

 

page:  只在当前jsp页面有效

request: 只在当前请求有效, 每次请求分别对应不同的request域对象

// session: 默认情况下,同一个浏览器来访问有效(发送同一个sessionid)

session : 只在一次会话中有效,会话结束就无法取到数据了 (特殊情况,发送Cookie)

application : 在一个web应用中有效 (只要服务器不关,web应用不移除就可以取数据)

四个域对象的范围由小到大排列依次为: page request session application

 

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

原则: 四个域对象在选择的时候,能用范围小的绝不用范围大的

page: 数据只是暂时存在集合,在jsp页面的其他地方要用,用page(页面中自定义的map)

        什么时候需要用map了,就用page

request:数据只是做显示的,看完了就没用了,就存request域

        请求转发, Servlet 产生的处理结果(数据) 交给jsp显示,

session:数据给用户看完了,一会还要用,会话结束了就没用了

        用户登陆,用户信息发给客户端看,看完了,一会访问别的页面还要看用户信息

        购物车,购物成功了,给用户看购物车,待会随时可以查看购物车

        请求重定向,因为是两次请求,第一次请求的数据,第二次请求还要看

application : 数据给一个用户用完了,别人还要用

           聊天室,聊天记录,需要给所有的用户看

           统计网站在线人数,所有人看到的应该是一个数

 

总结: 需要定义Map不如用page,请求转发Servlet带给jsp的数据存request

    请求重定向带过去的数据存Session,全局的数据存application

 

五、 jsp 细节

只有当jsp页面指定的page指令isErrorPage为true时,才有exception隐式对象

Session对象不是每个jsp页面都能用的  前提是 page指令的session属性为true

 

Jsp注释:

 

jsp 出错

1)被翻译的Servlet不能编译,语法错,这时会报告是因为jsp中的哪行导致不能编译

2)翻译的Servlet 在运行期间出现异常, 报告是jsp的哪行导致的异常

    此时会进一步报告导致异常的原因,在Servlet中的哪行出现异常

2. jsp 映射也是通过servlet 元素

 

六、内省(neixing)

1. javabean

    固定写法的java类

    1)必须有无参构造函数

    2)属性必须私有,我们称为字段

    3)提供标准的getter和setter

    例: name 字段的getter: String getName()  settter: void setName(String name)

   

2. 什么是内省

内省: 通过反射的方式访问javabean

Jdk中的api :PropertyDescriptor类操作Bean的属性

 

3.BeanUtils工具包

Apache组织开发了一套用于操作JavaBean的API(内省)

核心类 BeanUtils

    setProperty(bean,name, value)

    copyProperties(target,source);

    可以支持String到8中基本数据类型转换

    其他引用数据类型都需要注册转换器ConvertUtils.register(Converter, Class)

 

3. WebUtils 工具类

    实现任何request提交的表单封装到对应的javabean

 

 

七、 jsp标签(可选)

为了移除jsp页面的java代码,sun公司提供了一些内置的标签

我们称为jsp标签,或jsp动作元素

 

1. <jsp:include> 相当于 RequestDispatcher 对象的页面引入

    dispatcher.include  实现 Servlet包含

    dispatcher.forward  实现servlet转发 

    forward在转发时 web容器会清空response中的数据

    在转发之后就无法向response写入数据

 

    动态引入方式,在程序运行期间引入,jsp被翻译成两个

    include指令也能实现页面的引入,静态引入,将两个jsp翻译成一个Servlet

 

    包含和被包含的jsp页面指令不能发生冲突

    其中,import和pageEncoding可以冲突

 

2. <jsp:forward> 实现请求转发

    结合 <jsp:param> 标签传参,自动进行url编码,编码的方式参照request编码

 

3. <jsp:useBean id class scope> 内省

    反射创建javabean,以id作为key存入指定的域

    其实在创建之前,会先去域中找,找到了则不创建

 

4. <jsp:setProperty> 设置属性值

    <jsp:setPropertyname=”user” property=”username” value=”zs” />

<jsp:setPropertyname=”user” property=”username” param=”username” />

    <jsp:setPropertyname=”user” property=”*” /> 批量

 

5. <jsp:getProperty> 获得属性值

 

八、web开发模式

Sun公司针对web开发提供了两种模式

Model1: jsp+javabean  只适合小型应用

Model2: servlet+jsp+javabean    mvc

 

九、el + jstl 入门

1. EL 全名为Expression Language。它是一种数据访问语言

    el表达式

2. EL 能实现如下功能:

    1)使用变量访问web域中存储的对象  ${user}

    2)访问javabean的属性 ${user.address.city }

    3)执行基本的逻辑运算

    4)直接使用隐式对象

    5)调用 el 函数

3. el 表达式用在哪里

    1)在 jsp 页面直接输出数据

    2)在标签中使用el直接为属性赋值

 

4. el 表达式获取数据

    在jsp页面使用el表达式可以轻松地获得web域中的对象

    并对 javabean 、 数组、 list 、 map 进行取值

 

5. 需要对 web 域中的 list 和map 集合进行迭代就需要结合 jstl 迭代标签

 

JSTL是sun公司开发的一套标签库

使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的脚本代码

 

在页面中使用JSTL标签需完成以下2个步骤:

1) 导入jstl.jar和standerd.jar这两个JSTL的jar文件。

2) 在JSP页面中使用<%@ tagliburi=“”  prifix=“” %>元素导入标签库。

 

最常用的 jstl 标签为 forEach 和 if 标签

<c:foreach var=”” items=””>

<c:if test=””>

 

6. el表达式可以进行逻辑运算

 

 

 

7. el表达式中的保留关键字

 

 

十、el 中的11 个隐式对象

 

隐含对象名称

      

pageContext

对应于JSP页面中的pageContext对象

pageScope

代表page域中用于保存属性的Map对象

requestScope

代表request域中用于保存属性的Map对象

sessionScope

代表session域中用于保存属性的Map对象

applicationScope

代表application域中用于保存属性的Map对象

param

表示一个保存了所有请求参数的Map对象

paramValues

表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]

header

表示一个保存了所有http请求头字段的Map对象

headerValues

同上,返回string[]数组。注意:如果头里面有“-”,例Accept-Encoding,则要headerValues[“Accept-Encoding”]

cookie

表示一个保存了所有cookieMap对象

initParam

表示一个保存了所有web应用初始化参数的map对象

 

隐式对象的具体用途

1. pageContext 

    获得servlet上下文路径 (web应用名称)

    ${pageContext.request.contextPath}

 

2. pageScope、requestScope、sessionScope、applicationScope

    准确地获得四个域中的对象,用于取值

 

3. param、paramValues

    获得请求参数,一般用于做表单的回显

 

4. header、headerValues

    获得请求消息头

 

5. cookie

    获得浏览器发送的cookie

    Cookie也是map集合,key是cookie的name value是对应的cookie对象

 

6. initParam

    获得web 初始化参数

 

十一、自定义EL表达式

调用普通Java类的静态方法(编写步骤就是自定义标签的步骤):EL函数

    1、编写一个普通的java类型,提供一个静态方法

           packagecom.itheima.functions;

 

           publicclass StringFunction {

              publicstatic String toUpperCase(String str){

                  returnstr.toUpperCase();

              }

           }

    2、在WEB-INF目录下建立一个扩展名为tld(Tag Libary Definition)的xml文件。

           <?xml version="1.0"encoding="UTF-8"?>

              <taglibxmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                  xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

                  version="2.0">

                  <tlib-version>1.0</tlib-version>

                  <short-name>myfn</short-name>

                  <uri>http://www.itheima.com/jsp/functions</uri>

                  <function>

                     <description>to uppercase</description>

                     <name>toUpperCase</name>

                     <function-class>com.itheima.functions.StringFunction</function-class>

                     <function-signature>java.lang.StringtoUpperCase( java.lang.String )</function-signature>

                  </function>

              </taglib>

           3、可选的。前提是第2步中的tld文件放到了WEB-INF目录中。

              修改web.xml,对tld中的uri与实际的tld文件进行对应

             

           <jsp-config>

              <taglib>

                  <taglib-uri>http://www.itheima.com/jsp/functions</taglib-uri>

                  <taglib-location>/WEB-INF/myfn.tld</taglib-location>

              </taglib>

             </jsp-config>

           4、在JSP中使用自定义的函数

           <%@tagliburi="http://www.itheima.com/jsp/functions"prefix="myfn"%>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值