zoukankan      html  css  js  c++  java
  • Servlet,jsp,JSP技术 ,JSP编程

     .Servlet

    思考

    1 浏览器可以直接打开JAVA/class文件吗? 不可以

    2浏览器可以打开HTML、JS 文件吗? 可以

    3 JAVA程序可以生成HTML文件吗?可以的,用IO流。

    4 浏览器解析的时候是需要HTTP协议的,JAVA普通类有没有HTTP协议呢? 普通类没有.

    JAVA-(class)浏览器如何访问呢?

    浏览器---HTML

    A   JAVA通过IO流生成HTML--->浏览器

    B   JAVA 需要加入HTTP协议

    解决上面2个问题可以通过 Servlet

    C  如何通过浏览器访问Servlet

       它需要用到一个文件web.xml (webroot-->web-inf--web.xml)

       

    Sevlet它是什么?

      Servlet是一个容器(引擎),它包含协议和支持功能的jar包,它是一个整体。

    在使用的时候我们不用去关心里面的核心程序,我们只关心业务程序。

    业务程序   程序员所写支持协议的类,有一种特殊的叫法 Serlvet类。

    1.三要素是什么

    入口(login.html)     处理(LoginServlet.java)  出口 (success.jsp)

    2.如何访问servlet

      http://IP:port/project/urlpattern

      urlpattern ---->web.xml中找

     

    3 request 和 response的区别?

    Request请求  Broswer---->Tomcat    login.html--->LoginSevlet.java

    Response返回 Tomcat---->Broswer   

     

    4 doGet  和  doPost的区别?

       doGet   <a href=url>  超链接用的默认方式 get   不解中文决乱么

                <form action=url  method=get >

               明文传递方式 浏览器中可以看到传递的信息

               不安全,并且数据量大的时候会缺损数据

       doPost   <form action=url  method=post >        解决中文乱码

                密文传递方式 浏览器看不到传递的信息

               安全,并且数据量大的时候不会缺损数据

     

    5如何解决乱码问题?

    Request请求有乱码    

    request.setCharacterEncoding("UTF-8");

    Reponse返回有乱

    response.setCharacterEncoding("UTF-8");

    6 如何取得请求中的值 ?

    String value=request.getParameter(“控件名”);   单个值

    String []  values=request.getParmeterValues(“控件名”);  同名多个值

     

    7 常见的错误:404 、500?

    404 路径错误---解决思路  跟踪路径

    500 代码错误---解决思路  jsp/servlet中代码错误

    获取不到值null  在console里面去找到错误的位置。

     

    8 servlet中得到流的方法?

       字符流   response.getWriter( )----->PrintWriter

       字节流   response.getOutputStream()-->OutputStream

     

    9 如何跳转到出口?

    //跳转并且可以传递数据

    request.getRequestDispatcher("success.jsp").forward(request, response);

     

    //重新定向 跳转不传递数据

    response.sendRedirect("success.html");

     

    10如何将数据传递到出口?

     //保存数据

    request.setAttribute("name", username);

    request.setAttribute("password", pwd);

     

     //获取数据

     用户名是:${ name}   ,密码: ${password}。

     

    11 Servlet的生命周期

       Servlet的生命周期是由tomcat服务器来控制的。

      1 构造方法:

    创建servlet对象的时候调用。默认情况下,第一访问servlet就会创建servlet对象只创建一次。说明servlet对象在tomcat中是单实例的。

     

     2初始化   init方法

      当创建完servlet对象的时候会调用init()方法,只调用一次。

     

    3 调用服务 service 方法   其中就包含doGet  doPost等方法

      每次发送请求的时候调用。可以调用n次。

    4 销毁 destory 方法

       销毁servlet对象的时候调用,停止服务器或者重新部署的web项目的时候销毁servlet就会调用destory方法

     

    12 Servlet时序图

    13 servlet自动加载

    在web.xml中加入

      <load-on-startup> 1</load-on-startup>

    里面的数字越小加载级别越高

    当tomcat启动的时候,就去运行web.xml解析里面的内容,当发现有自动加载的数据时候,就会运行加载。

      <servlet>

        <servlet-name>sl</servlet-name>

        <servlet-class>com.bw.servlet.LoginServlet</servlet-class>

          <load-on-startup>3</load-on-startup>

      </servlet>

    14 ServletConfig 对象

       主要是加载servlet的初始化参数,在web应用中可以存在多个ServletConfig对象

      

      <servlet>

        <servlet-name>sl</servlet-name>

        <servlet-class>com.bw.servlet.LoginServlet</servlet-class>

         <init-param>

          <param-name>username</param-name>

          <param-value>godyang</param-value>

        </init-param>

        <init-param>

          <param-name>password</param-name>

          <param-value>123456</param-value>

        </init-param>

      </servlet>

    15 ServletContext对象

     上下文对象,表示当前的web应用(项目)环境。一个web应用只有一个ServletContext对象

     

      上下文参数配置  它是全局的  所有的servlet都可以访问

    <context-param>

    <param-name>ecode</param-name>

    <param-value>UTF-8</param-value>

    </context-param>

    // 获取上下文对象

    ServletContext sc = this.getServletContext();

    String contextParamValue = sc.getInitParameter("ecode");

    System.out.println("contextParamValue=" + contextParamValue);

    //项目路径

    String path=sc.getContextPath();

    System.out.println("path="+path);

    //文件发布后(tomcat/webapps)的真实路径

    String realPath=sc.getRealPath("counter.txt");

    System.out.println("realPath="+realPath  );

    //获取文件流

         InputStream  is=sc.getResourceAsStream("C:\Tomcat\webapps\webThree\WEB-INF\classes\counter.txt");

     

     

    二.JSP技术

    Jsp技术是用来开发java web的页面显示的,所有MVC模型里面的视图层,所以视图层的开发
    jsp不是编程语言,java server pages的缩写
    Jsp其实也是继承Servlet的,属于在服务器上的开发。Servlet是用于java语言的动态资源开发的技术,而Jsp是把java和html结合,在html中可以写java语言,主要用在页面的显示开发上。

    1.1.Jsp的特点

    1.Jsp的运行必须交给tomcat服务器。tomcat的work目录就是服务器用来存放jsp运行时的临时文件的
    2.Jsp页面即可直接写html代码,也可以直接写java代码

    2.Jsp的执行过程
    问题1:访问http://localhost:8080/hello/index.jsp 如何显示效果?
    1.访问到index.jsp页面,tomcat扫描到jsp文件,在tomcat/work目录下把jsp文件翻译成java源文件

        index.jsp-->index_jsp.java(翻译)

    2.tomcat服务器把java源文件编译成class字节码文件(编译)

      index_jsp.java-->index_jsp.class

    3.tomcat服务器构造index_jsp类对象
    4.tomcat服务器调用index_jsp类里面的方法,返回内容显示到浏览器
    如果是第一次访问当前jsp文件时,执行步骤是:1-->2-->3-->4
    第N次访问jsp时,执行步骤是:4,不再执行其他步骤

    注意:jsp文件被修改或者jsp的临时文件被删除了,要重新走翻译 1 和编译 2  的过程

    问题2:既然jsp是servlet,那么jsp的生命周期和servlet的生命周期是不是一样的?
    当jsp文件被翻译成java的源码时,可以在翻译出来的源码文件里看到当前访问的jsp文件继承HttpJspBase类,再通过查询JDK,可以发现HttpJspBase又是继承于HttpServlet的。所以,可以得到结论,jsp既是一个servlet的程序,而servlet的技术可以用在jsp程序中,但是并不是所有的servlet技术全部适用于jsp程序

    Servlet的生命周期:
    1.构造方法(第一次访问执行)默认情况第一次使用的时候 通过单例模式创建一个servlet对象
    2.init方法初始化(第一次访问执行)当构造了之后就会调用初始化方法 只调用一次
    3.service方法(每n次访问都会执行)每次发出请求的时候调用可以调用n次
    4.destory方法(退出时执行)关闭服务软件重新部署的时候销毁 servlet对象

     
    Jsp的生命周期:
    1.翻译:Jsp-->java文件
    2.编译:java-->class文件(servlet程序)
    3.构造方法(第一次访问时执行)
    4.init方法(第一次访问):_JspInit()
    5.service方法:_JspService()
    6.destory方法:_jspDestory()

     

    问题3:JSP和Servlet作用有什么区别?

    1.Servlet作用: 用java语言开发动态资源(  java 流 )的技术.

    2.JSP 作用:用java语言开发动态(java 流)+静态资源(html)的技术

    3.Jsp语法


    3.1.Jsp模板
    JSP 页面中会自动添加HTML代码内容,该JSP是模板
    这些模板定义了网页的基本骨架,也就是说定义了页面的结构和外观
    3.2.Jsp表达式
    JSP的表达式作用是向浏览器输出变量的值或表达式计算的结果

        语法:<%=变量或表达式 %>
        例如<% String name="Eric";%>

    <%=name%>
    注意:
    1.表达式的原理即使翻译成out.print("变量“);通过该方法向浏览器写出内容。
    2.表达式后面不需要带分好结束


    3.3.Jsp的脚本

    脚本是指在JSP页面编写多行java代码的,可以执行java代码
        语法:<%多行java代码; %>

    如:

     <%
          Date date = new Date();
            
          SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
        
          String now = sdFormat.format(date);
        
        out.println(now);
        
        %>
    注意
    1.原理是把脚本中的java代码原封不动的拷贝到jspService方法中执行
    2.jsp脚本中写的java是需要加分好的,语法跟java语法是一样的
    3.多个脚本片段中的代码可以相互访问
    4.单个脚本片段中的java语句可以是不完整的,但是,多个脚本片段组合后的结必须是完整的java语句

    3.4.Jsp的声明
    JSP的声明是用来声明变量或者方法的,如果在index.jsp页面内声明一个变量或者方法,则该变量或者方法是index_jsp类的成员变量,成员方法,即是全局变量。这个其实就是在类中写好方法,然后可以在jsp_service方法中调用其他方法。
    jsp通过脚本也可以定义一个变量,但是这个变量是保存在index_jsp类下的jspService方法下的一个变量,由于是保存在方法下面,所有脚本里是不可以定义一个方法的,只能通过声明来定义方法。
    注意以上两者的区别,一个是保存在类下面,称为成员变量或者成员方法,另一个则是保存在方法中,称之为局部变量

        语法:<%! 变量或方法%>

    作用:声明JSP的变量和方法
    注意:
    1.变量翻译成成员变量,方法翻译成成员方法

    3.5.Jsp的注释

    jsp的注释格式:

        jsp的注释:<%!--jsp注释 --%>
        html的注释:

    注意:
    1.html的注释会被翻译和执行,无论在jsp的页面翻译之后的源码还是在浏览器上查看网站的源码,都是可以查看到的。但是jsp的注释是不会被翻译和执行的,在翻译之后源码里是不能找到的,从浏览器查看源码也是查看不到的

    4.Jsp的三大指令

    JSP指令是为JSP引擎而设计的,他们并不产生任何可见的输出,只是告诉引擎如何处理jsp页面中的其余部分。jsp定义的有三大指令,分别是:include,page,tagllb

    4.1.Include指令

    Include指令的作用是当前页面包含其他页面,主要是导入其他jsp文件

        语法:<%@include file="common/header.jsp%>

    注意
    1.原理是把被包含的页面(header.jsp)的内容翻译到包含页面(index.jsp)中,合并并翻译成一个java源文件,再编译运行!!,这种包含就加叫静态包含(源码包含)
    2.如果使用静态包含,被包含页面中不需要出现全局的html标签了,(如html,body,head)

    4.2.page指令
    page指令的作用是告诉tomcat服务器如何翻译jsp文件
                          
        语法:<%@ page contentType="text/html;charset=UTF-8" language="java" %>

    <%@ page 

    language="java"        --使用的语言

    import="java.util.*"   --需要导入的类

    pageEncoding="UTF-8"   --jsp编码方式

    contentType="text/html; charset=UTF-8" --tomcathtml流发送给浏览器的文件类型和编码方式

    errorPage="error.jsp"   --当前jsp页面解析错误的时候就会跳转到error.jsp

    isErrorPage="false"  --当前页面是不是错误导向页面

     %>

     language="java"--告诉服务器只用什么动态语言来翻译jsp文件
    import="java.util.*" --告诉服务器java文件使用什么包,导入多个包时,用逗号隔开
    pageEncoding="utf-8" --告诉服务器使用什么编码把jsp翻译成java文件
    contentType="text/html; charset=utf-8" --服务器发送浏览器的数据类型和内容编码,在开发工具中,只需要设置pageEncoding即可解决中文乱码的问题
    errorPage="error.jsp" --如果当前页面出现错误信息,则自动调用此处指定的错误页面
    isErrorPage="false" --意思是当前页面为错误页面,默认为false,当设置为true时就认为是一个错误处理页面,就可以在页面中使用<%=exception.getMessage()%>方法来获取错误异常信息,使其在页面上可以显示
    全局配置错误处理页面
    在web.xml中配置如下:
        <!--全局错误处理页面配置-->
        <error-page>
            <error-code>500</error-code>
            <location>common/500.jsp</location>
        </error-page>
        <error-page>
            <error-code>404</error-code>
            <location>common/404.html</location>
        </error-page>

    配置之后,不用在jsp页面中特别指明,会自动跳转的
    session="true" --是否开启Session功能,false时不能使用Session内置对象,ture时可以使用。默认为true
    buffer="8kb" --页面的缓存区大小。
    isELIgnored="false" --是否忽略EL表达式。

    page==this 对象 一般用在编译指令中 <%@ page   %>

    4.3.tagllb指令

     语法<%taglib  %>

       作用:标签指令 用来解析标签效果

      <%@taglib  prefix="c"  uri="http://java.sun.com/jsp/jstl/core"  %>

    5.JSP的内置对象

    5.1.什么是内置的对象
    service开发中会经常用到一些常用的类比如:HttpSession, ServletConfig, ServletContext, HttpServletRequet,用的时候,我们会直接创建就可以了,但是在jsp中这会经常使用到这些类。为了开发的方便,sun公司在设计jsp的时候,在jsp页面加载完毕以后就自动帮开发者创建好了这些对象,而开发者只需要直接使用这些对象就可以了,那么这些已经创建好的对象有一个统一的名字叫做内置对象,内置对象一共有九个

    例如:
    在Service中要使用Session,需要先HttpSession session = request.getSession(true); 来创建一个Session对象,然后在使用对象的方法
    但是在JSP中,可以直接使用Session的方法,如session.getId();

    九大内置对象

    jsp

    servlet

     

    对象名

    类型

    使用范围

    request

    HttpServletRequest

    请求 浏览器--->服务器

    response

    HttpServletResponse

    返回 服务器--->浏览器

    config

    ServletConfig

    用来获取web.xml中的信息

    application

    ServletContext

    整个项目中的全局信息

    exception

    Thrawable

    捕获异常 try/catch  throws

    page

    this

    当前对象,当前页面对象

    out

    JspWriter---->PrintWriter

    当前页面输出流

    pageContext

    PageContext

    当前页面的上下文,整个页面

    Session

    HttpSession

    会话  浏览器和服务器通讯


    即:
    1.对象名(request)-->类型HttpServletRequest :HTTP请求的时候使用到
    2.对象名(response)-->类型HttpServletResponse :HTTP响应的时候用到
    3.对象名(config)-->类型ServletConfig :获取属于自己的参数
    4.对象名(application)-->类型ServletContext :获取全局参数

    5.对象名(exception)-->类型Throwable :异常
    6.对象名(page)-->类型 Object(this) :本jsp对象
    7.对象名(out)-->类型JspWriter :打印到浏览器
    8.对象名(pageContext)-->类型PageContext

    9.对象名(session)-->类型HttpServletSession :会话管理使用


    5.2.Out对象

    out  对象  JspWriter 带缓冲的PrinterWriter  就是输出流 , 使用范围是当前页面,超出了当前页无效

    1.PrintWriter: 直接向浏览器输出内容
    用write直接向浏览器(输出)写出内容

    2.JspWrite: 向Jsp 缓冲区写内容
    用write向jsp的缓冲区写内容,当缓冲区满足一下条件的时候,把内容一起写到浏览器上,性能高于PrintWriter
    当满足一下条件之一,JSP缓冲区内容写出到浏览器:
       (1) 缓冲区满了
        (2)刷新缓存去:out.flush();
        (3)关闭缓冲区:buffer="0kb";
        (4)执行完毕JSP页面

    ‘out.print()

    ‘out.println();


    5.3.pageContext对象

    前面已经有了8个内置对象,这些对象都是在jsp_service方法中被创建的,然后直接使用,但是由于是在方法中被创建,属于局部变量,所以很难在其他方法被调用,所有,使用了PageContext把这八个内置对象封装起来,这样传参的时候只需要传一个就可以了,然后通过这个PageContext来调用
    除了调用其他八个内置对象意外,PageContext本身也是一个域对象,可以传递参数,准确的说PageContext是jsp的上下文对象,只可以在当前jsp文件内传参

    分别介绍PageContext的两个方法:
    1.可以获取其他八个内置对象
    源码分析:

    public class 01_hello_jsp {
                        public void _jspService(request,response){
                            创建内置对象
                            HttpSession session =....;
                            ServletConfig config = ....;

                            把8个经常使用的内置对象封装到PageContext对象中
                            PageContext pageContext  = 封装;
                            调用method1方法
                            method1(pageContext);
                        }
                        
                        public void method1(PageContext pageContext){
                            希望使用内置对象
                            从PageContext对象中获取其他8个内置对象
                            JspWriter out =pageContext.getOut();
                            HttpServletRequest rquest =     pageContext.getRequest();
                            ........
                        }
                }

    注意:调用的时候,使用getout,getrequest等方法来调用
    使用场景:在自定义标签的时候,PageContext对象对象频繁使用到

    2.PageContext本身就是一个域对象
    经常使用的域对象有4个,分别是
    ServletContext           context域
    HttpServletRequest    request对象
    HttpSession               session域
    PageContex               page域

    PageContext域的作用是保存数据和获取数据,用于共享数据
    常用方法如下:
    保存数据
    1.默认情况下,保存到page域
    pageContext.setAttribute("name");

    2.可以向四个域对象保存数据
    pageContext.setAttribute("name",域范围常量)

    获取数据
    1.默认情况下,从page域获取
     pageContext.getAttribute("name")

    2.可以从四个域中获取数据

    pageContext.getAttribute("name",域范围常量)

    3.自动在四个域中搜索数据
        pageContext.findAttribute("name");
        顺序: page域 -> request域 -> session域- > context域(application域)

    5.4.page对象 page==this 对象 一般用在编译指令中 <%@ page   %>

    5.5.request对象 

    request 请求  浏览器到服务器

    当前请求存属性值

    request.setAttribute("name","godyang");

    当前请求取值

    request.getAttribute("name")

    请求传递参数

    <a href="b.jsp?name=shunshun">  b.jsp</a>

    或者

      <form  action="b.jsp"  method=post  >

       <input  type=text name="name" value="shunshun" />

       </form>

     

    取得请求参数的值

    request.getParameter(参数名);  request.getParameterValues(参数名)

    5.6.reponse 对象
    reponse  返回  服务器返回到浏览器

    获取返回流

    PrintWriter out = response.getWriter();

    返回内容形式

    response.setContentType("text/html");

    返回的编码

    response.setCharacterEncoding("UTF-8");

    页面重定向

    response.sendRedirect("index.jsp");

    浏览器端保存cookie对象

    response.addCookie()

     

     

     

    5.7.session对象 

    session 会话  浏览器和服务器通讯    当浏览器关闭的时候会话结束

    当浏览器第一访问服务器的时候就会产生一个会话

    保存会话信息

     session.setAttribute("uname","abc");

    获取会话信息

     session.getAttribute("uname");

    5.8.application对象

    application 应用   tomcat启动的时候整个项目就是一个应用

       当把值存入应用中,只有当tomcat关闭的时候才销毁

    保存应用信息

    application.setAttribute("app","appInfo");

    获取应用信息

     application.getAttribute("app");

    5.9.JSP中的四个域对象
    四个域度对象
        pageContext   page域
        request           request域
        session           session域
        application     context域

    1.域对象作用
    保存数据和获取数据,用于数据共享

    2.域对象方法
    setAttribute("name",Object)保存数据
    getAttribute("name")获取数据
    removeAttribute("name")消除数据

    域对象的作用范围

        page域 :只能在当前jsp页面中使用(当前页面)
        request : 只能在同一个请求中使用(转发)
        Session : 只能在同一个会话(session对象)中使用(私有的)
        context : 只能在同一个web应用中使用(全局的)

    5.10.JSP的最佳实践
    Servlet技术:开发动态资源。是一个java类,最擅长写java代码
    JSP技术:开发动态资源,通过java代码最擅长输出html代码

    一个在web项目中涉及到的逻辑:
    1.接收参数
    2.处理业务逻辑
    3.显示数据到浏览器
    4.跳转到其他页面

    最佳实践中,对上述逻辑进行分工,由Servlet和JSP联合完成
    Servlet:
    1.接收参数
    2.处理业务逻辑
    3.把结果保存到域对象中
    4.跳转到jsp页面

    JSP:
    1.从域对象中取出数据
    2.把数据显示到浏览器

    Servlet的数据-->JSP页面

    6.EL表达式
    6.1.EL表达式的作用
    EL表达式也是用在html页面中的,目的是简化JSP操作,代码。
    在最佳实践中,总结得出JSP中尽量不要写java代码,最好的方法就是不写,所以的逻辑全部放到Servlet中,所有的数据展示放在JSP中
    JSP的核心语法: jsp表达式 <%=%>和 jsp脚本<% %>。

    现在使用EL表达式来替换到JSP的表达式
    EL表达式的作用:向浏览器输出”域对象中的“变量值或表达式计算的结果!,注意一定要是域对象中的

        语法:${变量或表达式}

    6.2.EL语法
    1.输出基本数据类型便变量
    1.1.从四个域获取
        输出普通字符串: ${name}
        若没有指定域,则域的搜索先后顺序: pageScoep / requestScope / sessionScope / applicationScope

    1.2.指定域获取
        ${pageScope.name},在pageScope域中查找name
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>测试jsp文件</title>
    </head>
    <body>
    <%
        String name = "roso";
        pageContext.setAttribute("name",name,PageContext.REQUEST_SCOPE);
        %>
    <br>
    EL表达式:${requestScope.name};
    <%--
        ${name}等价于pageContext.findAtribute("name")
    --%>
    </body>
    </html>

    2.输出对象的属性值
    输出对象属性: ${student.name} 注意: .name 相当于 .getName()方法
    如果我们定义了一个Student类,并定义了name成员变量,这个时候可以通过${student.name}来获取name值
    点 . 方法是其实是调用getXX()方法

    3.输出集合对象
    集合对象有List和Map
    输出List集合: ${list[0].name } 注意: [0] 相当于 get(下标)方法
    输出map集合: ${map[key].name} 注意: [key]相当于get(key)方法
    中括号[]其实是调用get
    EL表达式没有遍历功能,但是可以结合标签使用遍历

    4.EL表达式计算
    表达式中需要注意的是字符串判空的一种方法${empty name}<br>

    示例代码:

    <%@ page import="servers.Student" contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page import="java.util.List" %>
    <%@ page import="java.util.ArrayList" %>
    <%@ page import="java.util.Map" %>
    <%@ page import="java.util.HashMap" %>
    <html>
    <head>
        <title>测试IE表达式</title>
    </head>
    <body>

    <%--1.EL输出对象的属性--%>
    <%
        //保存数据
        Student student = new Student("eric", 20);
        //放入域中
        pageContext.setAttribute("student",student);
    %>

    <%--2.EL输出集合List对象--%>
    <%
        //List
        List<Student> list = new ArrayList<Student>();
        list.add(new Student("rose",18));
        list.add(new Student("jack",20));
        list.add(new Student("luck",38));
        //List放到域中
        pageContext.setAttribute("list",list);
    %>

    <%--3.EL输出集合Map对象--%>
    <%
        //Map
        Map<String,Student> map = new HashMap<String, Student>();
        map.put("100",new Student("mark",20));
        map.put("101",new Student("maxwell",30));
        map.put("102",new Student("Eric",40));
        //放入域中
        pageContext.setAttribute("map",map);
    %>

    <%--3.EL表达式--%>
        <%--3.1.算术表达式--%>
        ${10+5}<br>
        <%--3.2.比较运算--%>
        ${10>5} <br>
        <%--3.3.逻辑运算--%>
        ${true && false} <br>
        <%--3.4.判空,null或空字符串--%>
        判断null:${name==null}<br>
        判断空字符串:${name==""}<br>
        判空: ${name==null || name==""}<br>
        判空的另一个种写法: ${empty name}<br>

    <%--1.使用EL获取对象--%>
    <%--实际调用student的getName方法获取的值--%>
    获取student的name属性值:${student.name}
    <%--${student.name}的点相当于调用getXX()方法--%>
    <br>


    <%--2.使用EL获取List对象--%>
    list对象:${list} <br>
    获取list的第一个对象:${list[0]} <br>
    获取list的第一个对象的name和age属性:${list[0].name} - ${list[0].age}
    <br>
    <%--${list[0]}等价于(ListpageContext.findAttribute("list)--%>
    <%--${list[0]}的中括号相当于调用get()方法--%>

    <%--3.使用EL获取Map对象--%>
    获取Map对象:${map}<br>
    获取key=100的值:${map['100'].name} - ${map['100'].age}
    </body>
    </html>

    7.JSP标签
    7.1.JSP标签的作用

    我们使用EL表达式来替换JSP的表达式,但是JSP还有一个经常会使用的语法,就是JSP脚本,出于和EL表达式同样的目的,我们使用标签来替代JSP脚本,以达到简化JSP页面的目的
    所以JSP标签作用:替换JSP脚本
    主要功能有:
    1.路程判断(if,for, 循环)
    2.跳转页面(转发,重定向)
    3.…………

    7.2.JSP标签的分类
    JSP的标签也分为几种类型的
        1.内置标签:,也叫动作标签,不需要在jsp页面中导入的标签
        2.JSTL标签:需要在jsp页面中导入的标签
        3.自定义标签:开发者自行定义,需要在jsp页面导入标签

    7.3.动作标签
    转发标签:
    参数标签:
    包含标签:
    包含标签的原理:
    包含与被包含的页面先各自翻译成java源文件,然后在运行时再合并在一起。(先翻译再合并),动态包含,使用include指令包含是静态包含
    静态包含 VS 动态包含
    1.语法不同

        静态包含语法:<%@inclue file="被包含的页面"%>
        动态包含语法: 

    2.参数传递不同

        静态包含不能向被包含页面传递参数
        动态包含可以向被包含页面传递参数

    3.原理不同

        静态包含: 先合并再翻译
        动态包含: 先翻译再合并


    7.4.JSTL标签
    JSTL的全名是:Java Standard Tag Libarary ---java标准标签库
    java标准标签库有五类,常用的是前三类

        标签核心库(c标签库) 天天用
        国际化标签(fmt标签库)
        EL函数库(fn函数库)
        xml标签库(x标签库)
        sql标签库(sqp标签库)

    7.5.使用JSTL标签的步骤
    1.导入jstl支持的jar包(标签背后隐藏的java代码)
    把包放在WEB-INF下的lib包
    2.使用tablib指令导入标签库

        <%@taglib prefix="简写" uri="tld文件的uri名称" %>
        uri从jstl.jar包下的META-INF下的tld文件中查找,把uri的值复制过来,prefix的值也是在tld中查找

    3.在jsp中使用标签
    核心标签库的重点标签
    保存数据:
    <c:set></c:set>
    获取数据:
    <c:out value=""></c:out>
    单条件判断:
    <c:if test=""></c:if>
    多条件判断:
    <c:choose></c:choose>
    <c:when test=""></c:when>
    <c:otherwise></c:otherwise>
    循环数据:
    <c:forEach></c:forEach>
    <c:forTokens items="" delims=""></c:forTokens>
    重定向:
    <c:redirect></c:redirect>
    代码示例:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%--导入标签库--%>
    <%@taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core"%>
    <html>
      <head>
        <title>JSTL核心标签</title>
      </head>
      <body>
      <%--使用标签--%>
      <%--1.set标签:保存数据(保存到域中),默认保存到page域中,可以指定--%>
      <c:set var="name" value="Eric" scope="request"></c:set>
      ${name}<br>
      ${requestScope.name}<br>
      <%--2.out标签:获取数据(从域中),当value值为null时,可以使用default指定的默认值,escapeXml标明默认值是原样输出还是转化为之后再输出,默认为true,表示原样输出--%>
      <%--双引号内虽然是name,但是现实的是字符串name,因为是在双引号内--%>
      <c:out value="name"/>
      <%--调用name的值正确写法--%>
      <c:out value="${name}" default="<h3>标题3</h3>" escapeXml="false"/><br>

      <%--3.if标签:单条件判断,如果test里面的EL表达式为真,则运行if包含的代码--%>
      <c:if test="${10>5}">
        条件成立
      </c:if>

      <%--4.choose标签+when标签+otherwirse标签:多条件的判断--%>
      <c:set var="score" value="86"></c:set>
      <c:choose>
        <c:when test="${score>=90 && score<=100}">
          优秀
        </c:when>
        <c:when test="${score>=80 && score<=90}">
          良好
        </c:when>
        <c:when test="${score>=70 && score<=80}">
          一般
        </c:when>
        <c:when test="${score>=60 && score<=70}">
          及格
        </c:when>
        <c:otherwise>
          不及格
        </c:otherwise>
      </c:choose>
    <br>
    <%--5.forEach:循环--%>
      <%
        //List
        List<Student> list = new ArrayList<Student>();
        list.add(new Student("rose",18));
        list.add(new Student("jack",20));
        list.add(new Student("luck",38));
        //List放到域中
        pageContext.setAttribute("list",list);
      %>
      <%
        //Map
        Map<String,Student> map = new HashMap<String, Student>();
        map.put("100",new Student("mark",20));
        map.put("101",new Student("maxwell",30));
        map.put("102",new Student("Eric",40));
        //放入域中
        pageContext.setAttribute("map",map);
      %>
      <%--<c:forEach
      begin="从哪个元素开始遍历,默认从0开始,可以不写"
      end="到哪个元素结束,默认到最后一个元素,可以不写"
      step="步长,默认是1,可以不写"
      var="每个元素的名称"
      items="需要遍历的数据(集合)"
      varStatus="当前正在遍历的元素的状态对象(count属性:当前位置,从1开始)"/>--%>
      <%--遍历list--%>
      <c:forEach begin="0" end="2" step="1" items="${list}" var="student" varStatus="varSta">
        姓名:${varSta.count}--${student.name}--年龄:${student.age}<br>
      </c:forEach>
      <%--遍历Map--%>
      <c:forEach items="${map}" var="entry">
        ${entry.key}--姓名:${entry.value.name}--年龄:${entry.value.age}<br>
      </c:forEach>

      <%--6.forToken标签:循环特殊字符串--%>
      <%
        String str = "java-php-net-平面";
        pageContext.setAttribute("str",str);
      %>
      <c:forTokens items="${str}" delims="-" var="s">
        ${s}<br>
      </c:forTokens>

      <%--7.重定向--%>
      <c:redirect url="http://www.baidu.com"/>
      </body>
    </html>

    8.自定义标签
    8.1.引入
    当现有的标签无法满足我们的需求时,就需要自己开发一个适合的标签
    例如,需要向浏览器输入当前客户端的IP地址,虽然用java程序是可以的,但是用标签是没有这个功能的,现在,我们来自定以这个标签

    8.2.第一个自定义标签开发步骤
    1.编写一个普通的类,继承SimpleTagSupport类,叫做标签处理器类

    /**
     * 标签处理类
     * 1.继承SimpleTagSupport
     */

    public class ShowIpTag extends SimpleTagSupport {

        /**
         * 2.覆盖doTag方法
         */
        @Override
        public void doTag() throws JspException, IOException {
            //向浏览器输出客户的IP地址
            PageContext pageContext = (PageContext)this.getJspContext();
            HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
            String ip = request.getRemoteHost();
            JspWriter out = pageContext.getOut();
            out.write("使用自定义标签输出客户的IP地址:"+ip);
        }
    }

    2.在web项目的WEB-INF目录下建立net.tld文件,这个tld叫标签的声明文件(参考核心标签库的写法)

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

    <taglib xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
            version="2.1">

        <!--标签库的版本-->
        <tlib-version>1.1</tlib-version>
        <!--标签库前缀-->
        <short-name>net</short-name>
        <!--tld文件的唯一标记-->
        <uri>http://gz.itcast.cn</uri>

        <!--一个标签的声明-->
        <tag>
            <!--标签名-->
            <name>ShoeIp</name>
            <!--标签处理器类的全名-->
            <tag-class>tag.ShowIpTag</tag-class>
            <!--输出标签体内容格式-->
            <body-content>scriptless</body-content>
        </tag>
    </taglib>

    3.在jsp页面的头部导入自定义标签库

        <%@taglib prefix="net" uri="http://gz.itcast.cn" %>

    4.在jsp中使用自定义标签

    8.3.自定义标签的执行过程
    问题: http://localhost:8080/hello/tag.jsp 如何访问到自定义标签?
    前提:tomcat服务器启动时,加载到每个web应用,加载每个web应用的WEB-INF目录下的所有文件,如web.xml, tld文件
    访问步骤:
    1.访问tag.jsp资源
    2.tomcat服务器把jsp文件翻译成java源文件-->编译class-->构造类对象-->调用_jspService()方法
    3.检查jsp文件的taglib指令,是否存在名为http://gz.itcast.cn的tld文件,如果没有,则报错
    4.上一步已经读取到net.tld文件
    5.在tag.jsp中读到,到net.tld文件中查询是否存在为ShoeIp的标签
    6.找到对应的标签,则读到内容
    7.得到tag.ShowIpTag
    8.构造ShowIpTag对象,然后调用ShowIpTag里面的方法

    8.4.自定义标签处理类的生命周期
    标签处理器本质上实现的还是SimpleTag接口,只是对里面的方法进行了重写。
    SimpleTag接口:
    void setJspContext(JspContext pc)
    设置pageContext对象,传入pageContext(一定调用)
    void setParent(JspTag parent)
    设置父标签对象,传入父标签对象,如果没有父标签对象,则调用此方法。通过geetParent()方法得到父标签对象
    void setXX(值)
    设置属性值
    void setJspBody(JSpFragment jspBody)
    设置标签体内容。标签提内容封装到JspFragment中,然后传入JspFragment对象,通过getJspBody()方法得到标签体内容,如果没有标签体内容,则不会调用此方法
    void doTag()
    执行标签时调用的方法(一定会调用)

    8.5.自定义标签的作用
    1.控制标签体内容的是否输出
    2.控制标签余下内容是否输出
    3.控制重复输出标签体内容
    4.改变标签体内容
    5.带属性的标签

        //1.声明属性的成员变量
        private Integer num;
        
        //2.关键点: 必须提供公开的setter方法,用于给属性赋值
        public void setNum(Integer num) {
            this.num = num;
        }

    自定义标签的作用代码示例:


    /**
     * 标签处理器类
     */
    public class TagDemo extends SimpleTagSupport {
        @Override
        public void doTag() throws JspException, IOException {
            System.out.println("执行了标签");
            /**
             *1. 控制标签内容是否输出
             * 输出:调用jspFrament.invoke();
             * 不输出:不调用jspFrament.invoke();
             */
            //1.1.得到标签体内容
            JspFragment jspBody = this.getJspBody();
            //执行invoke方法:会把标签体的内容输出到指定的Writer对象
            //1.2.往浏览器输出,writer为null就是默认往浏览器输出
    //        JspWriter out = this.getJspContext().getOut();
    //        jspBody.invoke(out);
            jspBody.invoke(null);//等价于上面的两行代码

            /**
             * 3.控制重复输出标签体内容
             * 方法:执行多次jspBody.invoke()方法
             */
            for (int i=1; i <= 5 ; i++) {
                jspBody.invoke(null);
            }


            /**
             * 4.改变标签提内容
             */
            //4.1.创建StringWriter临时容器
            StringWriter sw = new StringWriter();
            //4.2.把标签提内容拷贝到临时容器
            jspBody.invoke(sw);
            //4.3.从临时容器中得到的标签
            String content = sw.toString();
            //4.4.改变内容
            content = content.toLowerCase();
            //4.5.把改变的内容输出到浏览器
            //不能使用jspBody.invoke()来输出,因为标签体内的内容并没有改变,改变的是容器里面的
            this.getJspContext().getOut().write(content);
            

            /**
             * 2.控制标签余下内容是否输出
             * 输出:什么都不做就会默认输出
             * 不输出:抛出有SkipPageException()异常则不输出
             */
            throw new SkipPageException();
            
        }
    }

    8.6.输出标签体内容格式
    JSP:在传统标签中使用。可以写和执行jsp的java代码
    scriptless:标签体不可以写jsp的java代码
    empty:必须是空标签
    tagdependent:标签体内容可以写jsp的java代码,但不会执行
    9.JavaBean

    JavaBaen,咖啡豆,是一种开发规范,可以说是一种技术

    JavaBaen就是一个普通的java类,只要符合以下规定才能称之为javaBean:
    1.必须提供无参构造方法
    2.类中属性都必须私有化
    3.该类提供公开的getter和setter方法

    javaBean的作用:
    用于方法数据,保存数据
    方法javaBean只能使用getter和seetter方法

    javaBean的使用场景:
    1.项目中用到实体对象(entity)符合javaBean规范
    2.EL表达式访问对象属性,${student.name}滴啊用getName()方法,符合javaBean规范
    3.jsp标签中的属性赋值,setNum(Integet num)。符合javaBean规范
    4.jsp页面中使用javaBean,符合javaBean规范

    javaBean在jsp页面中的使用

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>jsp页面中使用javabean</title>
    </head>
    <body>
    <%--创建对象,使用无参构造器--%>
    <jsp:useBean id="stu" class="servers.Student"/>

    <%--赋值--%>
    <jsp:setProperty name="stu" property="name" value="jacky"/>

    <%--获取--%>
    <jsp:getProperty name="stu" property="name"/>

    </body>
    </html>

  • 相关阅读:
    java下载url图片链接
    mysql 设计索引的原则
    169. 多数元素
    263. 丑数
    markdown 语法笔记
    70.爬楼梯
    540. 有序数组中的单一元素
    88. 合并两个有序数组
    面试题57
    152. 乘积最大子序列
  • 原文地址:https://www.cnblogs.com/yuguangblog/p/6216115.html
Copyright © 2011-2022 走看看