• 梳理一下web总的一些概念


    servlet中的类适合繁复翻看文档,熟悉各个类的常用方法,看一些经典的案例代码。

    ServletConfig

    每个项目有多个servlet,每个servlet对应一个ServletCOnfigt对象。ServletConfig中封装的是每个servlet的配置信息,具体而言就是web.xml中<servlet></servlet>中的配置内容。

    可以使用HttpSerlet的this.getSerletConfig方法获得servletconfig

    ServletContext:

    每个项目对应一个ServletContext,ServletContext实体封装的内容对应web.xml中的配置信息,这包含的内容就比较的多了。在一个servlet中可以使用thi.getServletConfig().getServletContext()获取ServletContext也可以使用直接使用this.getServletContext()直接获取,后者中也是调用的第一个的方法。

    从上面就就可以看出来,ServletContext的范围比ServletConfig的范围更大一些。


    servlet中的域对象

      ServletContext,HttpServletRequest,HttpSession。

    jsp中的域对象(当然都是jsp9大内置对象)

      applicaltion,HttpServletRequest,HttpSession,PageContext。application其实就是ServletContext(可以直接查看jsp翻译成的java文件)

    servlet中的域对象只有三个,jsp中的域对象是servlet中的三个域对象再加一个jsp特有的pagecontext。

    pageContext是使用最多的一个内置对象,可以通过pageContext获取其余八个内置对象。

    #获取数据

    1)默认情况下,从page域获取

    pageContext.getAttribute("name")

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

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

    域范围常量:

    PageContext.PAGE_SCOPE

    PageContext.REQUEST_SCOPE

    PageContext.SESSION_SCOPE

    PageContext.APPLICATION_SCOPE

    3)自动在四个域中搜索数据

    pageContext.findAttribute("name");

    顺序: page-> request-> session- > context域(application域)这展示了四个域的大小

    page域: 只能在当前jsp页面中使用(当前页面)

    request域: 只能在同一个请求中使用(转发)

    session域: 只能在同一个会话(session对象)中使用(私有的)

    context域: 只能在同一个web应用中使用。(全局的)

    Servlet技术: 开发动态资源。是一个java类,最擅长写java代码

    jsp技术: 开发动态资源。通过java代码最擅长输出html代码。


    有个不成文的准则,尽量在jsp页面中不写java脚本,为了达到这一目的,jsp中的标签应运而生。

    jsp中的标签替换java脚本。

    jsp中的EL表达式替换jsp中的输出脚本。


    EL表达式

    其初衷是为了替换掉,jsp中向浏览器中输出内容的脚本:<%= %> <% %>

    基本语法:{$变量或者表达式},集体如下:

    1)输出基本数据类型变量

    1.1 从四个域获取

    ${name},会自动按照从小到大的域搜索,相当于pageContext.findAttribute(“name”) page->request->session->application

    1.2 指定域获取

    ${pageScope.name}

                        域范围: pageScoep / requestScope / sessionScope / applicationScope

    分别对应于: page request session application

        2)输出对象的属性值

    Class Student

    {

    String name,id;

    Public void setId();

    Public void setName();

    Public String getId();

    Public String getName();

    }

    {$stu.name}就是输出Student就会调用getName一定注意el表达式中的后面应当就是getName方法去掉get的内容。

    3)输出集合对象

       List  Map,一样遵守上面的规则。

    假设listmap中中存放了若干个Student,那么获取liststudent的属性:

    {$list[0].id} - {$list[0].name},list[0]相当于((List)pageContext.findAttribute(list)).get(0)

    {$map[100.name]}

    4EL表达式计算

    ${10*5 }

    ${10!=10 }

    ${true && false }

    判断null${name==null }

    判断空字符: ${name=="" }


    jsp中标签的分类

    • 内置标签(action动作标签): 不需要在jsp页面导入标签
    • jstl标签: 需要在jsp页面中导入标签
    • 自定义标签 : 开发者自行定义,需要在jsp页面导入标签

    下面就是分别围绕这三种标签展开介绍

    动作标签(内置标签)

    内置标签 就是在jsp的空间里面

      转发标签: <jsp:forward />

                参数标签:  <jsp:pararm/>

    包含标签:  <jsp:include/>

    原理: 包含与被包含的页面先各自翻译成java源文件,然后再运行时合并在一起,相当于一种调用

    (先翻译再合并),动态包含

    静态包含  vs  动态包含的区别?

    1) 语法不同

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

    动态包含语法: <jsp:include page="被包含的页面">

    2)参数传递不同

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

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

    3)原理不同

    静态包含: 先合并再翻译

    动态包含: 先翻译再合并

    ======================================

    JSTL标签

    JSTL (全名:java  standard  tag  libarary   -  java标准标签库  )

    核心标签库 c标签库) 天天用 c core

    国际化标签(fmt标签库)

    EL函数库(fn函数库)

    xml标签库(x标签库)

    sql标签库(sql标签库)

    使用jstl标签的步骤

    1) 导入jstl支持的jar包(标签背后隐藏的java代码)<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

    注意:使用javaee5.0的项目自动导入jstl支持jar,否则就要自己导入。

    2)使用taglib指令导入标签库

    <%@taglib uri="tld文件的uri名称" prefix="简写" %>

    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>

    jsp文件的html标签之前使用tablib导入标签库

    <%@taglib uri = “路径” prifix = “shotname”/>其中uriprefix可以到对应标签包的tld文件中查看

    核心标签forEach的使用实例:

    <body>
        <%--使用标签 --%>
        <%--set标签 :保存数据(保存到域中)默认保存到page域 --%>
        <c:set var="name" value="rose" scope="request"></c:set>
        
        <%
            String msg = null;
            pageContext.setAttribute("msg",msg);
         %>
        
        ${msg }
        <br/>
        <%--out标签: 获取数据(从域中)
        default: 当value值为null时,使用默认值
        escapeXml: 是否对value值进行转义,false,不转义,true,转义(默认)
        --%>
        <c:out value="${msg}" default="<h3>标题3</h3>" escapeXml="true"></c:out>
        
        <hr/>
        
        <%--if标签 :单条件判断--%>
        <c:if test="${!empty msg}">
            条件成立
        </c:if>
        
        <hr/>
        <%--choose标签+when标签+otherwirse标签: 多条件判断 --%>
        <c:set var="score" value="56"></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>
        
        <%-- forEach标签:循环 --%>
        <%
            //List
             List<Student>  list = new ArrayList<Student>();
             list.add(new Student("rose",18));
             list.add(new Student("jack",28));
             list.add(new Student("lucy",38));
             //放入域中
             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("narci",40));
             //放入域中
             pageContext.setAttribute("map",map);
         %>
         <hr/>
         <%--
          begin="" : 从哪个元素开始遍历,从0开始.默认从0开始
          end="":     到哪个元素结束。默认到最后一个元素
          step="" : 步长    (每次加几)  ,默认1
          items="": 需要遍历的数据(集合)
          var="": 每个元素的名称
          varStatus="": 当前正在遍历元素的状态对象。(count属性:当前位置,从1开始)
          
         --%>
        <c:forEach items="${list}" var="student" varStatus="varSta">
            序号:${varSta.count} - 姓名:${student.name } - 年龄:${student.age}<br/>
        </c:forEach>
        
        <hr/>
        
        <c:forEach items="${map}" var="entry">
            ${entry.key } - 姓名: ${entry.value.name } - 年龄:${entry.value.age }<br/>
        </c:forEach>
        <hr/>
        <%-- forToken标签: 循环特殊字符串 --%>
        <%
            String str = "java-php-net-平面";
            pageContext.setAttribute("str",str);
         %>
        
        <c:forTokens items="${str}" delims="-" var="s">
            ${s }<br/>
        </c:forTokens>
        
        <%--redrict:重定向 --%>
        <c:redirect url="http://www.baidu.com"></c:redirect>
        
      </body>

    自定义标签

    2.1 引入

    需求: 向浏览器输出当前客户的IP地址 (只能使用jsp标签)

    2.2 第一个自定义标签开发步骤

    1)编写一个普通的java类,继承SimpleTagSupport类,叫标签处理器类

    /**

     * 标签处理器类

     * @author APPle

     * 1)继承SimpleTagSupport

     *

     */

    public class ShowIpTag extends SimpleTagSupport{

    private JspContext context;

    /**

     * 传入pageContext

     */

    @Override

    public void setJspContext(JspContext pc) {

    this.context = pc;

    }

    /**

     * 2)覆盖doTag方法

     */

    @Override

    public void doTag() throws JspException, IOException {

    //向浏览器输出客户的ip地址

    PageContext pageContext = (PageContext)context;

    HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();

    String ip = request.getRemoteHost();

    JspWriter out = pageContext.getOut();

    out.write("使用自定义标签输出客户的IP地址:"+ip);

    }

    }

    2)在web项目的WEB-INF目录下建立itcast.tld文件,这个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>itcast</short-name>

      <!-- tld文件的唯一标记 -->

      <uri>http://gz.itcast.cn</uri>

      <!-- 一个标签的声明 -->

      <tag>

        <!-- 标签名称 -->

        <name>showIp</name>

        <!-- 标签处理器类的全名 -->

        <tag-class>gz.itcast.a_tag.ShowIpTag</tag-class>

        <!-- 输出标签体内容格式 -->

        <body-content>scriptless</body-content>

      </tag>

    </taglib>

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

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

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

    <itcast:showIp></itcast:showIp>

    2.3 自定义标签的执行过程

    问题: http://localhost:8080/day14/01.hellotag.jsp  如何访问到自定义标签?

    前提: tomcat服务器启动时,加载到每个web应用,加载每个web应用的WEB-INF目录下的所有文件!!!例如。web.xml, tld文件!!!

    1)访问01.hellotag.jsp资源

    2tomcat服务器把jsp文件翻译成java源文件->编译class->构造类对象->调用_jspService()方法

    3)检查jsp文件的taglib指令,是否存在一个名为http://gz.itcast.cntld文件。如果没有,则报错

    4)上一步已经读到itcast.tld文件

    5)读到<itcast:showIp> itcast.tld文件中查询是否存在<name>showIp<tag>标签

    6)找到对应的<tag>标签,则读到<tag-class>内容

    7)得到 gz.itcast.a_tag.ShowIpTag

    构造ShowIpTag对象,然后调用ShowIpTag里面的方法

    2.4 自定义标签处理器类的生命周期

    SimpleTag接口:

    void setJspContext(JspContext pc)  --设置pageContext对象,传入pageContext(一定调用)

    通过getJspCotext()方法得到pageContext对象

    void setParent(JspTag parent)  --设置父标签对象,传入父标签对象,如果没有父标签,则不 调用此方法。通过getParent()方法得到父标签对象。

    void     setXXX()             --设置属性值。

    void setJspBody(JspFragment jspBody) --设置标签体内容。标签体内容封装到JspFragment对象 中,然后传入JspFragment对象。通过getJspBody()方法 得到标签体内容。如果没有标签体内容,则不会调 用此方法

    void doTag()                     --执行标签时调用的方法。(一定调用)

    2.5 自定义标签的作用

    1)控制标签体内容是否输出

    2)控制标签余下内容是否输出

    3)控制重复输出标签体内容

    4)改变标签体内容

    5)带属性的标签

    步骤:

    5.1 在标签处理器中添加一个成语变量和setter方法

    //1.声明属性的成员变量

    private Integer num;

    //2.关键点: 必须提供公开的setter方法,用于给属性赋值

    public void setNum(Integer num) {

    this.num = num;

    }

    2.6 输出标签体内容格式

    JSP   在传统标签中使用的。可以写和执行jspjava代码。

    scriptless:  标签体不可以写jspjava代码

    empty:    必须是空标签。

    tagdependent : 标签体内容可以写jspjava代码,但不会执行。

     案例

    核心标签库: c:if   c:choose+c:when+c:otherwise   c:forEach

    高仿核心标签库

    Myeclipse中,alt+shift+z可以进入一种选择模式

    选中一块内容,然后ctrl+f,使用正则表达式 ^(.*)$ ^表示行首,$表示行为,.代表任意字符,*表示至少一次。替换为1;其中1表示前面组()的引用,表示把前面的内容后面替换为;

    制作<itcast:login>标签:

    对应的标签处理器类LoginTag.class

    public class LoginTag extends SimpleTagSupport{

    private String username;

    private String password;

    public void setUsername(String username) {

    this.username = username;

    }

    public void setPassword(String password) {

    this.password = password;

    }

    @Override

    public void doTag() throws JspException, IOException {

     HttpServletResponse response = (HttpServletResponse)((PageContext)this.getJspContext()).getResponse();

     //设置输出内容类型和编码

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

     String html = "";

     html += "<center><h3>用户登陆页面</h3></center>";

     html += "<table border='1' align='center' width='400px'>";

     html += " <tr>";

     html += " <th>用户名:</th>";

     html += " <td><input type='text' name='"+username+"'/></td>";

     html += " </tr>";

     html += " <tr>";

     html += " <th>密码:</th>";

     html += " <td><input type='password' name='"+password+"'/></td>";

     html += " </tr>";

     html += " <tr>";

     html += " <td colspan='2' align='center'><input type='submit' value='登陆'/> <input type='reset' value='重置'/></td>";

     html += " </tr>";

     html += "</table>";

    JspWriter out = this.getJspContext().getOut();

    out.write(html);

    }

    }

    对应的tld文件

    <tag>

        <name>login</name>

        <tag-class>gz.itcast.b_cases.LoginTag</tag-class>

        <body-content>scriptless</body-content>

        <attribute>

         <name>username</name>

         <required>true</required>

         <rtexprvalue>false</rtexprvalue>

        </attribute>

        <attribute>

         <name>password</name>

         <required>true</required>

         <rtexprvalue>false</rtexprvalue>

        </attribute>

      </tag>

    实现自己的<itcast:choose><itcast:when><itcast:otherwise>标签。注意对应的编前处理类中的设计技巧,这里的choose标签是whenotherwise的父标签,我们给父标签处理类中设置一个变量用来在子标签之间传递信息,但是注意父标签中的这个变量不是父标签的属性。

    先看自定义标签的使用:

    <body>

        <itcast:choose>

    <itcast:when test="${10<5}">

    条件成立

    </itcast:when>

    <itcast:otherwise>

    条件不成立

    </itcast:otherwise>    

        </itcast:choose>

      </body>

    各个标签处理类的设计

    public class ChooseTag extends SimpleTagSupport {

    //不是属性,而是临时变量,用于在子标签之间传递数据

    private boolean flag;

    public boolean isFlag() {

    return flag;

    }

    public void setFlag(boolean flag) {

    this.flag = flag;

    }

    @Override

    public void doTag() throws JspException, IOException {

    //输出标签体内容,可能是when或者otherwise中的内容

    this.getJspBody().invoke(null);

    }

    }

    public class WhenTag extends SimpleTagSupport {

    private boolean test;

    public void setTest(boolean test) {

    this.test = test;

    }

    @Override

    public void doTag() throws JspException, IOException {

    //根据test的返回值决定是否输出标签体内容

    if(test){

    this.getJspBody().invoke(null);

    }

    //获取父标签

    ChooseTag parent = (ChooseTag)this.getParent();

    parent.setFlag(test);

    }

    }

    public class OtherwiseTag extends SimpleTagSupport {

    @Override

    public void doTag() throws JspException, IOException {

    //通过父标签传递,when标签中test的值

    //获取父标签

    ChooseTag parent = (ChooseTag)this.getParent();

    boolean test = parent.isFlag();

    if(!test){

    this.getJspBody().invoke(null);

    }

    }

    }

    线面是自定义的foreach标签

    Tld文件

    <tag>

        <name>forEach</name>

        <tag-class>myjstl.ForEachTag</tag-class>

        <body-content>scriptless</body-content>

        <attribute>

         <!-- 标签名称 -->

         <name>var</name>

         <!-- 这个属性是不是必须的 -->

         <required>true</required>

         <!-- 是否支持el表达式 -->

         <rtexprvalue>false</rtexprvalue>

        </attribute>

        <attribute>

         <name>items</name>

         <required>true</required>

         <rtexprvalue>true</rtexprvalue>

        </attribute>

      </tag>

    标签处理类

    public class ForEachTag extends SimpleTagSupport

    {

    private Object items; // 需要遍历的数据,list或者map

    private String var; // 遍历的变量的名称

    public void setItems(Object items) {

    this.items = items;

    }

    public void setVar(String var) {

    this.var = var;

    }

    @Override

    public void doTag() throws JspException, IOException {

    PageContext context =  (PageContext) this.getJspBody().getJspContext();

    Collection coll = null;

    if(items instanceof List){

    coll = (Collection) items;

    }

    if(items instanceof Map){

    Map map = (Map) items;

    coll = map.entrySet();

    }

    for(Object obj : coll){

    context.setAttribute(var, obj);

    //每次循环 都显示 标签体的内容

    this.getJspBody().invoke(null);

    }

    }

    }

    Jsp页面中的使用

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

     <%

        List<Student> list = new ArrayList<Student>();

        list.add(new Student("100", "mike"));

        list.add(new Student("101", "jane"));

        list.add(new Student("102", "mary"));

        list.add(new Student("103", "jordan"));

        pageContext.setAttribute("list", list);

        

        Map <String, Student> map = new HashMap<String, Student>();

        

        map.put("001", new Student("101", "mike"));

        map.put("002", new Student("102", "kang"));

        map.put("003", new Student("103", "mary"));

        map.put("004", new Student("104", "jane"));

        pageContext.setAttribute("map", map);

         %>

    <itcast:forEach var = "stu" items = "${list }">

    ${stu.id }--${stu.name }<br/>

    </itcast:forEach>

    <itcast:forEach var = "entry" items = "${map}">

         ${entry.key }--${entry.value.id}--${entry.value.name }<br/>

        </itcast:forEach>


    JavaBean

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

     JavaBean就是一个普通的java类。只有符合以下规定才能称之为javabean

      1)必须提供无参数的构造方法

      2)类中属性都必须私有化(private)

      3)该类提供公开的getter setter方法

    JavaBean的作用: 用于封装数据,保存数据。

    访问javabean只能使用gettersetter方法

    以下方法哪些属于javabean的规范的方法? 答案 :( 1356  )

    注意: boolean类型的get方法名称叫 isXXX()方法

    1getName()    2)getName(String name)

    3)setName(String name)   4)setName()

    5) setFlag(boolean flag)   6)isFlag()

  • 相关阅读:
    AS3邮件
    JavaScript中this关键字使用方法详解
    AS3嵌入字体
    xp双击打不开jar包解决方案
    查询在表1表2中都存在,在表3中不存在的SQL(前提:表结构相同)
    这是否为复制Bug?求解!
    批处理添加允许弹出临时窗口站点
    SQL Server 合并IP
    C#学习笔记一(变量、属性、方法,构造函数)
    SQLServer事务的隔离级别
  • 原文地址:https://www.cnblogs.com/OliverZhang/p/6043322.html
Copyright © 2020-2023  润新知