梳理一下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()

 

posted @ 2016-11-08 15:46  zhangoliver  阅读(232)  评论(0)    收藏  举报