JSP使用

Jsp网页的组成

模板数据

静态部分,web容器不作处理,如HTML标签。

元素

  • 脚本元素
  • 指令元素
  • 动作元素

Jsp 脚本元素类型

脚本元素 脚本语法
声明 <%! 声明%>
脚本 <% 脚本%>
脚本表达式 <%= 脚本表达式%>

说明:各个脚本类型的普通格式都有其对应的XML兼容格式,其区别在于:对普通格式页面的访问,会以HTML文件的形式显示,而访问对应的XML兼容格式时,会以XML文件的形式显示。

<%!声明%>

声明语句用于声明方法和变量,对应的XML兼容格式为

 <jsp:declaration></jsp:declaration> 
                `<html>
                    <head><title>HelloWorld</title></head>
                    <body>
                        <%! public long fact(long x){//声明
                                if(x == 0) return 1;
                                else return x * fact(x - 1);
                            }       
                        %>
                        <table border="1">
                            <tr><th>x</th><th>x!</th></tr>
                            <% for(long i = 0; i < 20; i++){  %><!--脚本-->
                            <tr>
                                <td><%=i %></td>
                                <td><%=fact(i) %></td>
                            </tr>
                            <%} %>
                        </table>
                    </body>
                </html>`

// 在声明中定义的变量是翻译成相应Java程序的成员变量, 在脚本中定义的变量是相应Java程序的局部变量。





<%脚本%>


  1. 普通格式
        在<%%>标签里面写入Java代码,访问时以HTML文件的形式呈现。
        '<html>
         <head><title>HelloWorld</title></head>
        <body>
             <%
             String str = "HelloWorld";
             out.println(str);
            %>
        </body>
        </html>'
        说明:脚本翻译成对应java程序的代码放在该java程序的_jspService()方法中,因此,在脚本中声明的变量是局部变量。    
    
  2. XML兼容格式
     在<jsp:scriptlet></jsp:scriptlet>标签间写入Java代码,访问时以XML文件的形式呈现。
             示例:
             '<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns="http://www.w3.org/1999/xhtml" version="2.0">  
                <html>  
                    <head><title>Simple jspx page </title> </head>  
                    <body>  
                    <jsp:scriptlet>  
                        String str = "hello" ;  
                        out.println(str) ;  
                    </jsp:scriptlet>  
                    </body>  
                </html>  
                </jsp:root>'
    



<%=脚本表达式%>


  脚本表达式用来显示动态生成的结果,对应的XML兼容格式为<jsp:expression></jsp:expression>。不能使用分号作为脚本表达式的结束符,脚本表达式可以是常量,也可以是动态计算出来的值。

        示例:
        '<html>
        <head><title>HelloWorld</title></head>
        <body>
            <%
                String str = "Hello World";
            %>
            <%=str %> 
        </body>
    </html>'
    说明:脚本表达式翻译成对应java程序的代码放在该java程序的_jspService()方法中的print()方法中。



JSP页面的注释


<%--注释内容--%>//jsp注释,注释内容不会翻译为java代码,浏览器和源码中无法看到。
//HTML注释,会翻译为对应的java代码,在浏览器中注释的内容不会显示,查看源代码看得到注释的内容。
<%//%>、<%/**/%>//java注释,会翻译为java代码,但是不作为响应的内容,浏览器和源码中无法看到。

例子

    '<html>
        <head><title>HelloWorld</title></head>
        <body>
            <% String str = "aaa"; %>
            <%--<%=str %> --%> //jsp注释
            <!--<%=str %> -->
    //HTML注释,无法在浏览器中看到,但可在网页源文件中看到<!--aaa--> 
            <% //String str2 = "bbb"; %> //java注释
        </body>
    </html>'



JSP指令元素


    JSP指令元素<%@指令类型 属性名=”属性值”%>用于提供整个JSP页面的相关信息,用来设定JSP页面的相关属性。

Page指令

page指令的功能是设定整个JSP页面的属性和相关功能,用于翻译阶段与web容器的通讯。

语法:<%@page属性名=”属性值”%>
对应的xml兼容格式语法为:<jsp:directive.page属性名=”属性值”/>

Page指令的属性

属性名 描述 默认值
language 脚本语言名称 “java”
info 网页信息
contentType MIME类型及字符编码 “text/html;charset=ISO-8859-1”
import 类和包 none
buffer 缓冲区大小 8192k
autoFlush 自动刷新 true
session 能否获取session对象 true
isThreadSafe 是否线程安全 true
errorPage 指定错误页面 none
isErrorPage 允许为错误页面 false
extends 指定父类

例子

    '<%@page contentType="text/html; charset=utf-8" info="aa" %>
    <!--翻译成的java代码为response.setContentType(“text/html;charset=utf-8”)-->
    <%@page import="java.util.Date"%>
    <!--翻译成的java代码为import java.util.Date-->
    <%@page import="java.text.SimpleDateFormat"%>
    <html>
        <head><title>pageTest</title></head>
        <body>
            <% 
                Date date = new Date(); 
                SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
             %>
            <h1>当前系统时间:<%=sd.format(date) %></h1>   
        <br></body>
    </html>'

include指令(静态包含):

include指令用于在JSP编译阶段插入一个包含文本或代码的文件,将文件中的文本静态地包含进当前JSP文件中,如:<%@include file=”hello.jsp”%>。静态包含的文本最好不要有HTML标签和body标签,因为被包含的文件的全部内容将被插入到JSP文件中include指令所在的地方,这些标签会同JSP文件中已有的同样的标签发生冲突,静态包含的文件名不能是变量名且不能传递参数。

taglib指令

taglib指令能让用户在页面中使用自定义的标签。
语法:<%@taglib uri=”uri” prefix=”tagPrefix”%>
对应的xml兼容格式语法为:<jsp:directive.taglib uri=”uri” prefix=”tagPrefix”/>

JSP动作元素

JSP动作利用XML语法格式的标记来控制Servlet引擎的行为。利用JSP动作可以动态地插入文件、重用JavaBean组件、重定向用户到另外的页面、为java插件生成HTML代码、实现页面与组件的通信。

<jsp:include/>动作(动态包含):

语法: <jsp:include page="localUrl" flush="true"/>,flush为true表示缓冲区满时,自动刷新页面。

<jsp:forward/>动作(页面转发):

语法:<jsp:forward page=”url”/>,相当于RequestDispatcher的forward方法, 将请求转发出去。

动态包含和静态包含的区别

☆ 根本区别在于包含的时机,静态包含是在编译期间包含,而动态包含是在运行期间包含。
☆ 静态包含的是代码,动态包含的只是响应的内容。
☆ 静态包含适用于包含静态页面,动态包含适用于包含动态页面。
☆ 静态包含不能传递参数,动态包含可以传递参数。

①    、编写includeTest1.jsp如下:
<body>
    <%
    int i=100;
    String str="includeTest1.jsp";
     %>
    <%=str %>中i值是:<%=i %><br>
    <jsp:include page="includeTest2.jsp"></jsp:include>
</body>
再编写includeTest2.jsp如下:
<body>
    <%
    int i=600;
    String str="includeTest2.jsp";
     %>
    <%=str %>中i值是:<%=i %>
</body>
启动tomcat,在浏览器中输入http://localhost:8080/myapp/includeTest1.jsp查看结果如下:
includeTest1.jsp中i值是:100
includeTest2.jsp中i值是:600
②   、将includeTest1.jsp改为如下:
<body>
    <%
    int i=100;
    String str="includeTest1.jsp";
     %>
    <%=str %>中i值是:<%=i %><br>
 <%@ include  file="includeTest2.jsp"%>
</body>
将includeTest2.jsp改为如下:
<body>
    <%=str%>中i值是:<%=i %>
</body>
在浏览器中输入:http://localhost:8080/myapp/includeTest1.jsp查看结果如下:
includeTest1.jsp中i值是:100
includeTest1.jsp中i值是:100
③   、从上例可知,动态包含时,包含和被包含的文件互不影响,只是将被包含文件编译执行后的结果放入了包含的文件中;静态包含相当于将被包含的文件中的文本直接放入了包含的文件中,然后编译执行。

JSP隐式对象

隐式对象就是不用实例化,可以直接在JSP页面中使用的对象,如下表所示:

对象 描述
request 代表与请求相关的HttpServletRequest对象
response 代表与响应相关的HttpServletResponse对象
PageContext 代表封装请求某个JSP页面时请求环境的PageContext对象
session 代表特定用户请求会话的HttpSession对象
application 代表web应用程序的ServletContext对象
out 代表与响应输出流相关的jspWriter对象
config 代表JSP页面的Servlet相关的ServletConfig对象
page 等于java中的this变量
exception JSP页面抛出的Throwable对象,这个对象只能在JSP错误页面中使用

out对象

out对象是一个输出缓冲流,用来给客户端返回信息,它是javax.servlet.jsp.JspWriter的一个实例。
out对象常用方法:
☆println():向客户端输出各种类型的数据
☆newLine():输出一个换行符
☆close():关闭输出流
☆flush():输出缓冲区里的数据
☆clearBuffer():清除缓冲区里的数据,同时把数据输出到客户端
☆clear():清除缓冲区里的数据,但不把数据输出到客户端
☆getBufferSize():返回缓冲区的大小

pageContext对象:

pageContext对象可以获取其他隐式对象、可以实现页面的转发和包含、可以用它对四个作用域空间进行数据的存取,它是javax.servlet.jsp.PageContext的实例。
① pageContext对象获取其他隐式对象:
☆getRequest :获得request隐式对象
☆getResponse:获得response隐式对象
☆getServletConfig:获得config隐式对象
☆getServletContext:获得application隐式对象
☆getPage:获得page隐式对象
☆getSession:获得session隐式对象
②pageContext对象对四个作用域空间进行数据的存取:
pageContext对象提供了四个常量,用来表示四个作用域:
☆PAGE_SCOPE:pageContext作用域,只在当前页面有效
☆REQUEST_SCOPE: request作用域,在forward转发的页面有效
☆SESSION_SCOPE:session作用域,IE浏览器未关闭就一直有效
☆APPLICATION_SCOPE:application作用域,未重启Tomcat就一直有效。
③pageContext对象实现页面的转发和包含:
pageContext.forward(String relativeURL);//实现页面的转发
pageContext.include(String relativeURL);//实现页面的包含

例子


例1,获取web.xml配置文件中jsp的初始化参数:
先在tomcat安装目录下的webapps目录中新建/myapp/WEB-INF/路径,并在WEB-INF目录中编写web.xml如下:

<web-app version="2.5" 
    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-app_2_5.xsd">
  <servlet>
    <servlet-name>param</servlet-name>
    <jsp-file>/get.jsp</jsp-file><!--指定jsp文件,路径相对于当前web项目文件夹-->
    <init-param><!--JSP的初始化参数-->
        <param-name>name</param-name>
        <param-value>zhangsan</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>param</servlet-name>
    <url-pattern>/get.jsp</url-pattern>

  </servlet-mapping>
</web-app>
然后在myapp目录中编写get.jsp如下:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
  <head>
    <base href="<%=basePath%>">
    <!--base标签设置当前页面的根路径,即当前页面的其他路径可以相对base标签设置的路径而设置-->
    <title>My JSP 'forward.jsp' starting page</title>
<%!
  public void jspInit() {//访问该jsp时执行该方法
    System.out.println("初始化");
}
public void jspDestroy() {//该jsp对应的Java程序(servlet)销毁时执行
      System.out.println("销毁");
}
%>
  </head>
<body>
<%  
    String param = config.getInitParameter("name");
//获取web.xml中jsp的初始化参数
    out.println("param-value  in web.xml is :"+param);
%><br/>
        basePath is  <%=basePath%>
  </body>
</html>
最后启动tomcat,在浏览器中输入:http://localhost:8080/myapp/get.jsp访问。

例2,在request作用域中传递绑定的对象:
先在tomcat安装目录下的webapps目录中新建myapp目录,然后在myapp目录中编写sendEmp.jsp如下:
<html>
<body>
<%      
request.setAttribute("emp","scott");
%> 
        <jsp:forward page="getEmp.jsp"></jsp:forward><!--请求转发-->
</body>
</html>
继续在myapp目录中编写getEmp.jsp如下:
<%
String emp = (String)pageContext.getAttribute("emp",PageContext.REQUEST_SCOPE);
String emp2 = (String)request.getAttribute("emp");//这句和上句意思一样
out.println(emp+" "+emp2);
%>
启动tomcat,在浏览器中输入:http://localhost:8080/myapp/sendEmp.jsp访问。

##另外
QQ截图20160415131256

QQ截图20160415131316

QQ截图20160415131546

QQ截图20160415131616

QQ截图20160415131622

QQ截图20160415131628

QQ截图20160415131641

QQ截图20160415131648

QQ截图20160415131655

面向对象设计原则

一些软件设计的原则
面向对象设计原则和创建SOLID应用的5个方法

迪米特法则

定义:

一个对象应该对其它对象保持最少的了解 从而降低类之间的耦合

具体来说对于对象 ‘O’ 中一个方法’M’,M应该只能够访问以下对象中的方法:

  1. 对象O
  2. 与O直接相关的Component Object
  3. 由方法M创建或者实例化的对象
  4. 作为方法M的参数的对象
    例子:demeter

SOLID 原则

单一职责 (SRP)

一个类发生变化的原因不应该超过一个。这意味着代码中每个类,或者类似的结构只有一个功能。
QQ截图20160413142903

里氏替换原则 (LSP)

子类必须能够替换成它们的基类。即:子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。另外,不应该在代码中出现if/else之类对子类类型进行判断的条件。里氏替换原则LSP是使代码符合开闭原则的一个重要保证。正是由于子类型的可替换性才使得父类型的模块在无需修改的情况下就可以扩展。
A. Derived types must be completely substitutable for their base types
B. This principle is just an extension of the Open Close Principle
C. Making sure that new derived classes are extending the base classes without
changing their behavior

QQ截图20160413145728

正方形不是矩形的例子

接口隔离原则 (ISP)

接口隔离原则(Interface Segregation Principle)指出客户不应该被强迫依赖于他们不使用的接口。当我们使用非内聚的接口时,ISP指导我们创建多个较小的内聚度高的接口。

当你应用ISP时,类和他们的依赖使用紧密集中的接口通信,最大限度地减少了对未使用成员的依赖,并相应地降低耦合度。小接口更容易实现,提升了灵活性和重用的可能性。由于很少的类共享这些接口,为响应接口的变化而需要变化的类数量降低,增加了鲁棒性。

A. Clients should not be forced to depend upon interfaces that they don’t use

QQ截图20160413153256

QQ截图20160413153318

依赖反转原则 (DIP)

依赖反转原则(Dependency Inversion Principle,DIP)指出高层次模块不应该依赖于低层次模块;他们应该依赖于抽象。第二,抽象不应该依赖于细节;细节依赖于抽象。方法是将类孤立在依赖于抽象形成的边界后面。如果在那些抽象后面所有的细节发生变化,那我们的类仍然安全。这有助于保持低耦合,使设计更容易改变。
A. High-level modules should not depend on low-level modules. Both should
depend on abstractions
B. Abstractions should not depend on details. Details should depend on
abstractions

QQ截图20160413154556

QQ截图20160413154612

QQ截图20160413155306

QQ截图20160413155326

开闭原则(OCP)

关于开发封闭原则,其核心的思想是:模块是可扩展的,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

A. Software entities like classes, modules and functions should be open for
extensionbut closedformodifications
B. The design and writing of the code should be done in a way that new
nctionality should be added with minimum changes in the existing code
C. The design should be done in a way to allow the adding of new functionality as
new classes, keeping as much as possible existing code unchanged

QQ截图20160413160021

QQ截图20160413160030

其它原则

参考第一个链接一些软件设计的原则
* Common Closure Principle(CCP)– 共同封闭原则
* Common Reuse Principle (CRP) – 共同重用原则
* Hollywood Principle – 好莱坞原则
* High Cohesion & Low/Loose coupling & – 高内聚, 低耦合
* Convention over Configuration(CoC)– 惯例优于配置原则
* Separation of Concerns (SoC) – 关注点分离
* Design by Contract (DbC) – 契约式设计
* Acyclic Dependencies Principle (ADP) – 无环依赖原则
* Don’t Repeat Yourself (DRY)
* Keep It Simple, Stupid (KISS)
* Program to an interface, not an implementation
* Command-Query Separation (CQS) – 命令-查询分离原则
* You Ain’t Gonna Need It (YAGNI)