JSP基础

来源:互联网 发布:java 数据库连接池 编辑:程序博客网 时间:2024/06/07 04:51

1.jsp是什么

是sun公司定义的一种规范.
JSP全称是JavaServer Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。JSP/Servlet规范。
JSP实际上就是Servlet
JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

2.jsp=html+java代码

这之后学的就是怎么样可以在jsp中不要写Java代码


3. 服务器是如何调用并执行一个jsp页面



4.服务器如何把Jsp页面中的html排版标签发送到客户端

都是在service()方法中:


5.Jsp页面中的java代码服务器是如何执行

<span style="font-size:18px;">out.write(new Date().toLocalString());</span>


6.Web服务器在调用jsp时,会给jsp提供一些什么java对象






7.Jsp的最佳实践

Jsp用来做页面

Servlet用来做业务逻辑


不管是JSP还是Servlet,虽然都可以用于开发动态web资源。
但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。
其原因为,程序的数据通常要美化后再输出:
让JSP既用java代码产生动态数据,又做美化会导致页面难以维护。
让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。
因此最好的办法就是根据这两门技术的特点,让它们各自负责各得,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。

改变页面的编码(设置页面的编码)

Window—Preferences—搜索jsp—

Encoding:ISO 10646/Unicode(UTF-8)

如果只在工程右击改的话,那么改的只是这个工程的

Jsp页面默认改为代码界面:

Open WIth--MyEcliipse JSP Editor:

Window—Preferences—

搜索:File Associations

File types:*.jsp

Associated editors:

MyEclipse JSP Editor.... 

点击Default


8.jsp的模板元素

     JSP页面中的HTML内容称之为JSP模版元素

     Html代码的发送:在service方法里面调用out.write()将模版代码发送到客户端。


   8.1 JSP脚本

         写在<%  %>里面的称为JSP脚本:java代码里面的语句结束要有分号。

   8.2 脚本表达式

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

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

          举例:当前时间:<%= new java.util.Date() %>

         JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端。
         JSP脚本表达式中的变量或表达式后面不能有分号(;
        
        “=”:代表输出
<body>     <%            request.setAttribute("name","张无忌");      %>       脚本表达式(输出一个变量):<%=request.getAttribute("name")%>运行结果:脚本表达式(输出一个变量:张无忌)

   8.3JSP脚本片段

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

<%

  多行java代码

%>

  l注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素,JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet_jspService方法中。
  lJSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。

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

      举例:

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


  l多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);
  l正规开发中的JSP中不应出现java脚本:标签封装

           输出一个表格:for循环的是jsp脚本:

             

     <table border=1 width=200>      <%         for(int i=1;i<=5;i++){         out.write("<tr><td>");         out.write(i+"");         out.write("</td><td>");         out.write("aaa");         out.write("</td></tr>");      }           %>       </table>
       

          此种做法显然太麻烦,

          换成如下写法:for循环的是html代码

          

      <table border=1 width=200>      <%         for(int i=1;i<=5;i++){         %>              <tr>                  <td><%=i+"" %></td>                  <td><%="aa" %></td>               </tr>         <%         }       %>       </table>
      运行结果:

      


9.输出表达式

即输出到页面的东西

 <%=name %>       out.print(name);
输出表达式后面不能加分号

10. Jsp的声明:

格式:<% !   %>

作用: 可以定义类变量和类方法,实例变量和实例方法.

<%!           public void demo(){               System.out.println("大家好");           }                       String name="令狐冲";                      public static void demo1(){                System.out.println("我是静态的方法");           }                      public class A{}      %>      <%           demo();           demo1();           out.write(name);      %>
     成为了内部类

    <%  %>在service()方法里面。

11.注释:

HTML注释:<!--   -->,页面源码能看到

Java注释: //  /*   */页面源码看不到

Jsp注释: <%--   --%> 页面源码看不到  ctrl+shift+/

                                    去掉:alt+shift+\


12.指令标签

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

  12.1 page

   Forward: 因为在web.xml中设置主页,不能在web.xml设置servlet文件,所以这时候就可以在jsp中做这个可以

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

用来说明页面的信息

Import:唯一一个可以写多个的属性。导入后,就可以在页面引用该后台的代码了

其他属性:

autoFlush=”true”:自动刷新,缓存区满了,自动由服务端向客户端发送信息。

buffer=”8k”:缓冲区

info:相当于键值对,

 

errorPage:当页面出现了异常:自动去哪一个页面

isErrorPage:把要去的那个页面表示成确实是一个错误页面

此种配置只适用于500的异常


lerrorPage属性的设置值为一路径(相对或绝对),如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前页面。
l可以在web.xml文件中使用<error-page>元素为整个WEB应用程序设置错误处理页面,其中的<exception-type>子元素指定异常类的完全限定名,<location>元素指定以“/”开头的错误处理页面的路径。
l如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。
<error-page>      <error-code>404</error-code>      <location>/8.jsp</location></error-page>

本身有错误的那个页面要设置page指令:errorPage=“7.jsp”

表明出现错误时要到达该页面。


当出现错误时要到的那个页面的page指令里必须写上isErrorPage=“true”

表明此页面就是来处理异常的页面。

可以通过异常对象拿到堆栈里的信息。

<body>     服务器正忙,请一会再来访问      <%           String reason=exception.getMessage();           out.write(reason);      %></body>     

Page指令解决JSP中文乱码:

lJSP程序存在有与Servlet程序完全相同的中文乱码问题
ü输出响应正文时出现的中文乱码问题

ü读取浏览器传递的参数信息时出现的中文乱码问题

lJSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题

üJSP引擎将JSP源文件翻译成的Servlet源文件默认采用ISO8859-1编码,而JSP
发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻
译成Servlet源文件时,需要进行字符编码转换。

ü如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的

   ISO8859-1字符集编码处理。

l如何解决JSP引擎翻译JSP页面时的中文乱码问题

ü通过page指令的contentType属性说明JSP源文件的字符集编码

üpage指令的pageEncoding属性说明JSP源文件的字符集编码

输出响应正文时出现的中文乱码问题:Response.setContentType();

 

读取浏览器传递的参数信息时出现的中文乱码问题:

Post方式:Request.setCharacterEncoding();

Get方式:new或修改服务器

 

JSP引擎将JSP源文件翻译成的Servlet源文件默认采用ISO8859-1编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换。

指定:pageEncoding

 

12.2 include 

<%@include file=”” %> : 静态包含 (是指的代码的拷贝)  (推荐)

指代码级别的包含,将目标页面的源码拷贝一份包含进来。

 

<jsp:include page=“” > : 动态包含 (是指的将目标页面的执行结果的包含)

指执行目标页面,将结果包含进来。

linclude指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。
l语法:

  <%@include file=“被包含组件的绝对URL或相对URL"%>

  其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用。

l细节:
被引入的文件必须遵循JSP语法。

被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSPfragments)作为静态引入文件的扩展名。

由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。 

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

12.3 taglib

标签库指令:导入标签库时用。


13.动作标签

JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。

 13.1 <jsp:forward>标签:请求转发


 13.2 <jsp:param>标签  

l当使用<jsp:include><jsp:forward>标签引入或将请求转发给其它资源时,可

以使用<jsp:param>标签向这个资源传递参数。

l语法1

  <jsp:includepage="relativeURL | <%=expression%>">

  <jsp:paramname="parameterName" value="parameterValue|<%= expression%>" />

  </jsp:include>


l语法2

  <jsp:forwardpage="relativeURL | <%=expression%>">

  <jsp:paramname="parameterName" value="parameterValue|<%= expression%>" />

  </jsp:include>


l<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值

。在<jsp:include><jsp:forward>标签中可以使用多个<jsp:param>标签来传递

多个参数。 

14: 九大内置对象(可以直接拿来用,不需要创建)

request:请求对象

response:响应对象

config:Servlet的一个配置对象

application:全局对象 每个应用只有一个

exception:异常对象 通常不处理该异常,将jsp编译成一个Servlet的时候,执行service方法,已经帮我们抛了异常,所以没必要再去做异常处理了

Session:会话对象

page:将JSP页面编译成一个Servlet类的时候,该类的一个实例对象

out:输出流对象

pageContext:


out:

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

lout对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter

  象非常相似。

lJSP页面中的out隐式对象的类型为JspWriterJspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer

  属性可以调整它的缓存大小,甚至关闭它的缓存。

l只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返

  回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
ü设置page指令的buffer属性关闭了out对象的缓存功能
üout对象的缓冲区已满
ü整个JSP页面结束
<body>      <%        out.write("abc") ;        response.getWriter().write("def") ;      %>  </body>
运行结果:def abc

Flush():清空缓存区,把缓存里的数据直接输出到页面:

 <body>      <%        out.write("abc") ;        out.flush() ;        response.getWriter().write("def") ;      %>  </body>
运行结果:abcdef



当在page指令出设置:表示没有缓冲:  buffer="0kb"

通常不会这样设,因为缓存可以提高效率

此效果和flush一样 flush:清空缓冲


<%  out.println("aaa");  response.getWriter().write("bbb"); %> 


PageContext: 

代表的是一个页面的上下文对象

a: pageContext 是一个域对象 : 范围就是本页面

    本身是一个域对象,存的数据只能当前页面来访问。
                 1.意味着底层是一个map :
                                 Map<String,Object>
                                           void setAttribute(key,value) ;   setAttribute(String name,Object value); 
                                                                                                setAttribute(String name,Object value,int scope);

                                           Object getAttribute(key) ;

                                             void removeAttribute() ;

<body>  <!-- pageContext对象的第一个作用:  1.  作为域对象      a.存储数据          -->      <%       pageContext.setAttribute("name", "张无忌") ;       pageContext.setAttribute("name1", "张三丰",PageContext.SESSION_SCOPE) ;      %>            <%      String name = (String) pageContext.getAttribute("name") ;        out.write(name) ;                String name1 = (String) session.getAttribute("name1") ;        out.write(name1) ;      %>  </body>

特点:放的数据,只能当前页面中来用



              2.pageContext提供了对其他三个域对象的访问
                         void setAttribute(String key,Object value,int scope)

                        void removeAttribute(String key,int scope)

                         Object getAttribute(String key,int scope)


Scope:

 PageContext.PAGE_SCOPE //本页面范围

PageContext.REQUEST_SCOPE  //请求范围

PageContext.SESSION_SCOPE  //会话范围

PageContext.APPLICATION_SCOPE //全局范围




      3.提供了查找数据的方法:


从四大域范围中查找数据

查找是依次从PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE,APPLICATION_SCOPE

四个范围去寻找,找到为止,找不到返回null)

Object obj = pageContext.findAttribute(String key)

Obejct findAttribute(key) ; 


从四个域对象里分别寻找数据

 <body>  pageContext对象从4个范围中寻找数据:            <%  // pageContext.setAttribute("name", "张三丰") ;    // request.setAttribute("name", "张无忌") ;    // session.setAttribute("name", "张翠山") ;       application.setAttribute("name", "张果老") ;      %>            <%         String name = (String) pageContext.findAttribute("name") ;         out.write(name) ;      %>  </body>

当寻找的属性不存在时,空指针异常


b: 提供了获取其他8大对象的方法

request.setAttribute("name", "ÕÅÈý") ;   

pageContext.getRequest().setAttribute("name","ÕÅÈý") ;

以上两句没有任何区别


<body>  pageContext对象的第二个作用: 获取其他8个对象      两种写法没有任何差别            <%            //底层用  页面不需要这样写    HttpServletRequest req = (HttpServletRequest) pageContext.getRequest() ;  req.setAttribute("name", "东方不败") ;    request.setAttribute("name", "张三丰") ;        %>            <%         String name = (String) pageContext.findAttribute("name") ;         out.write(name) ;      %>  </body>

c: 提供了转发和包含的简易方法

<body>  pageContext对象的第三个作用: 请求转发和请求包含            <%   request.setAttribute("name", "东方不败") ;  //请求转发不用拿取请求转发器了 :  //pageContext.forward("/7.jsp") ;    //请求包含:  pageContext.include("/7.jsp") ;      %>        </body>

d:有几个jsp提供的标签,动态标签只是标签,并不是java代码


15.Out对象的输出问题




16、四大域对象(相当重要)

 PageContext:页面范围的数据。用的很少

 ServletRequest:请求范围的数据。用的很多。显示一次数据后就没有用了,这样的数据应该放到该范围中

 HttpSession:会话范围的数据。用的很多。每次请求和响应都需要共享的数据。比如登录信息,购物信息。

 ServletContext:应用范围的数据。用的不多。所有客户端都共享的信息。注意同步。

                              数据能不能取到,关键是不是从一个地方取的数据


l到此为止,web开发接触到了4个域对象,这4个域对象是学习web的重点,也是笔试经常考察的知识点
pageContext(称之为page域)
request(称之为request域)
session(称之为session域)
servletContext(称之为application域)
l明确如下问题:
什么是域?
这4个对象的生命周期?
哪种情况下用哪种域对象。
1、request:如果客户向服务器发请求,产生的数据,用户看完就没用了,像这样的数据就存在request域,像新闻数据,属于用户看完就没用的
2、session:如果客户向服务器发请求,产生的数据,用户用完了等一会儿还有用,像这样的数据就存在session域中,像购物数据,用户需要看到自己购物信息,并且等一会儿,还要用这个购物数据结帐
3、servletContext:如果客户向服务器发请求,产生的数据,用户用完了,还要给其它用户用,像这样的数据就存在servletContext域中,像聊天数据


17、JavaBean的概念(相当重要)

1、什么是JavaBean(VO:Value Object;DO:Data Object;POJO:最简单的java对象,DTO              Data Transfer Object)

遵循一定的命名规则:

必须有默认的构造方法

类的声明为public类型

字段都是私有的     private boolean married;

提供公有的getter或setter方法(属性)。getMarried=isMarried  setMarried

一般实现java.io.Serializable接口(序列化接口)

 

2、实际开发中有什么用?

封装数据,便于传递数据。


lJavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
这个Java类必须具有一个无参的构造函数
字段必须私有化。
私有化的字段必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
l虽然Sun公司在定义JavaBean规范时,允许Java开发人员把JavaBean设计得可以像Swing组件一样功能强大,但在实际的J2EE开发中,通常只使用到以上JavaBean最基本的特性。
lJavaBean在J2EE开发中,通常用于封装数据,对于遵循以上写法的JavaBean组件,其它程序可以通过反射技术实例化JavaBean对象,并且通过反射那些遵守命名规范的方法,从而获知JavaBean的属性,进而调用其属性保存数据。

lJavaBean的属性可以是任意类型,并且一个JavaBean可以有多个字段。每个字段通常都需要具有相应的setter、getter方法,setter方法称为属性修改器,getter方法称为属性访问器。
l属性修改器必须以小写的set前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如,name属性的修改器名称为setName,password属性的修改器名称为setPassword。
l属性访问器通常以小写的get前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name属性的访问器名称为getName,password属性的访问器名称为getPassword。
l一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。


在jsp中操作javabean

使用动作元素(内置标签)

jsp:useBean:用于从指定范围根据名称查找JavaBean,如果没有找到,创建该JavaBean的实例,然后放到指定的范围中。如果找到了,直接取出来用。

属性:

id:查找的bean的名称。

class:查找的bean的类全名(包名.类名)

scope:指定查找的范围

默认值page,从PageContext页面范围找

可选值:

request,从ServletRequest中找,请求范围

session,从HttpSession中找,会话范围

application,从ServletContext中找,应用范围

 jsp:setProperty:给指定名称的bean的属性设置值。调用setter方法

属性:

property:对应的是JavaBean中的setter方法

name:指定那个bean

value:设置的值

param:请求参数的名称


jsp:getProperty:把指定名称的bean的属性的值打印到页面上

如果一个属性的值为null,界面就会显示null,不爽

属性:

property:对应的是JavaBean中的setter方法

name:指定那个bean

<body>   <!-- userbean标签相当于   User user = new User() ;-->   <jsp:useBean id="user" class="com.heima.bean.User" ></jsp:useBean>      <jsp:setProperty property="name" name="user" value="张无忌"/>      <jsp:getProperty property="name" name="user"/>     </body>

User.java:
package com.heima.bean;import java.io.Serializable;public class User implements Serializable{private String name ;private String age ;private String sex ;private String address ;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}

11.jsp:

<body>                     封装表单用的   <form action= "/day12_00_jsp/12.jsp" method="post">   姓名:<input type = "text" name = "name"><br>   年龄: <input type = "text" name = "age"><br>   性别:<input type = "radio" name = "sex" value = "男">                男<input type = "radio" name = "sex"  value = "女">女<br>   地址:<input type = "text" name = "address">   <input type = "submit" value = "提交">   </form>          封装超链用的   <a href = "/day12_00_jsp/12.jsp?name=abc&age=30">封装数据</a>           封装转发标签的数据用的   <jsp:forward page="/12.jsp?name=abc">请求转发 服务端跳转 不用加工程名    <jsp:param value="15" name="age"/>    <jsp:param value="beijing" name="address"/>   </jsp:forward>     </body>

12.jsp:
<body>  用user对象封装数据:   <% request.setCharacterEncoding("UTF-8"); %>    <jsp:useBean id="user" class="com.heima.bean.User"></jsp:useBean>    param对应表单控件的名字     把页面上名字叫name的控件(param="name")里面的内容封装到user对象(name="user")的name属性(property="name")中    <jsp:setProperty property="name" name="user" param="name"/>     <jsp:setProperty property="age" name="user" param="age"/>    <jsp:setProperty property="sex" name="user" param="sex"/>    <jsp:setProperty property="address" name="user" param="address"/>        <jsp:getProperty property="name" name="user"/>:    <jsp:getProperty property="age" name="user"/>:    <jsp:getProperty property="sex" name="user"/>:    <jsp:getProperty property="address" name="user"/><br>  <hr>  采用内省机制进行封装:<br>   由服务器帮我们找param,不用我们指定  要求页面上的控件的名字和javabean里面的名字一一对应<jsp:setProperty property="*" name="user"/>  <jsp:getProperty property="name" name="user"/>:    <jsp:getProperty property="age" name="user"/>:    <jsp:getProperty property="sex" name="user"/>:    <jsp:getProperty property="address" name="user"/><br>  <hr>  封装超链的数据:<br>    <jsp:useBean id="user1"  class="com.heima.bean.User" ></jsp:useBean>    <jsp:setProperty property="*" name="user1"/>         <jsp:getProperty property="name" name="user1"/>    <jsp:getProperty property="age" name="user1"/>      <hr>  封装转发标签的数据:<br>    <jsp:useBean id="user2"  class="com.heima.bean.User" scope="session"></jsp:useBean>    <jsp:setProperty property="*" name="user2"/>        <jsp:getProperty property="name" name="user2"/>    <jsp:getProperty property="age" name="user2"/>    <jsp:getProperty property="address" name="user2"/>   <a href = "/day12_00_jsp/13.jsp">13.jsp</a>  </body>

运行结果:








 

























0 0
原创粉丝点击