目前基于java的开发基本稳定。

前者降低了开发、部署成本。

在需要具有高度伸缩性、高度稳定性的企业应用里,如银行系统、保险系统,以EJB3+JPA为核心的经典JavaEE应用具有广泛占用率。可参考《经典JavaEE企业应用实战》。

 

理解EJB3和spring容器中的Bean、EJB容器和spring容器之间的联系和区别。

spring本身也是一个容器,只是EJB容器管理的是EJB,spring容器管理的是普通的Java对象。

 

对已有的知识进行归纳、总结。将新的知识与已掌握的知识进行类比。

 

安装mysql选择GBK的编码方式。

 

为异构系统的良好整合提供了保证。

 

面向对象建模的思维方式

 

不仅要考虑系统开发过程,还要考虑系统后期的维护、扩展。

在原来基础上延伸。新开发的系统要能与老系统有机融合。

 

只要有通用的接口,组件之间就可以良好协作。各组件之间支持热插拔,各组件之间的影响非常小。

 

致力于让应用的各组件以松耦合方式组织在一起,让应用之间的耦合停留在接口层次,而不是代码层次。

职责单一才能提供重用性。

 

企业应用开发有两个重要的关注点:可维护性和复用。

可维护性——>分层;

稳定的软件;

抽象成基础类库。

要有自己的基础类库。框架也是一套基础类库,它抽象了软件开发的通用步骤。

 

web.xml中使用<context-param>元素配置的参数对整个web应用有效。因此称为web应用的配置参数。

 

Tomcat7.0才支持servlet3.0规范。

jdk1.5建议使用Tomcat5.5系列。

Jdk1.6建议使用Tomcat6.0系列。 

 

1、In Action

Servlet、Jsp:每个servlet在容器中只有一个实例。服务器端负责解析请求头/请求参数的是jsp或servlet。

真正提供HTTP服务的是Servlet。

Servlet3.0提供了异步请求、Annotation、增强的Servlet API,这些功能简化了Java web开发。

 

在严格的JavaEE应用中,中间层的组件会将应用底层的状态信息封装成JavaBean集,也叫DTO,并将这些DTO传到JSP页面,让JSP可以显示应用的底层状态。

 

Jsp2.2、servlet3.0规范,需要使用支持JavaEE6规范的应用服务器或支持servlet3.0的web服务器,如Tomcat7.0。

 

对于web应用而言,客户端浏览器无法直接访问WEB-INF路径下的任何内容。

在servlet2.5规范之前,java web应用的大部分组件(jsp、servlet、filter、listener)都通过web.xml配置管理,servlet3.0规范可通过Annotation来配置管理web组件。

 

web.xml配置管理:

a、配置JSP

b、配置和管理servlet

c、配置和管理Listener

d、 配置和管理filter

e、配置标签库

f、配置JSP属性

g、配置和管理JAAS授权认证

h、配置和管理资源引用

i、web应用首页

 

每个web容器都会提供一个系统的web.xml文件,用于描述所有web应用共同的配置属性。如Tomcat的系统web.xml放在Tomcat的conf路径下,而Jetty的系统web.xml文件放在Jetty的etc路径下,文件名为webdefault.xml。

 

jsp声明:<%! 声明部分   %>,jsp声明会将转换成对应servlet的成员变量或成员函数。

jsp被翻译成servlet类后会被实例化,此servlet实例就一直存在于内存中。每个servlet在容器中只有一个实例。因此,在jsp中声明的变量是成员变量,成员变量只在创建实例时初始化,该变量的值将一直保存,直到实例销毁。

 

输出表达式值:<%=表达式%>,用于输出在页面显示。输出表达式语法后不能有分号。

 

jsp脚本: <% %>

jsp脚本里可以包含任何可执行的java代码。此脚本里的代码会转换成servlet的service()方法里的可执行代码。

 

jsp的3个编译指令:是通知JSP引擎的消息,它不直接生成输出。编译指令都有默认值。

<%@ page 属性名="属性值" %>

<%@ include 属性名="属性值" %>,静态包含,会把目标页面的其它编译指令也包含进来。

<%@ taglib 属性名="属性值" %>

 

JSP内建了异常机制支持,所以JSP可以不处理异常。若JSP页面在运行中抛出未处理的异常,系统将自动跳转到errorPage属性指定的页面。若errorPage没有指定错误页面,系统将直接把异常信息呈现给客户浏览器——这是所有开发者都不愿意的。

isErrorPage="true",指定此页面就是一个错误处理页面。

注: JSP的异常处理机制对JSP声明不起作用。

 

pageEncoding:指定生成网页的编码字符集。

 

若不使用import导入类,就必须使用全限定类名,即必须带包名。

 

jsp的7个动作指令:只是运行时的动作。

<jsp:include>指令,不会导入被include页面的编译指令,仅仅将被导入页面的body内容插入本页面。

 

Jsp脚本中的9个内置对象:此9个内置对象都是Servlet API接口的实例。直接使用此对象即可。

application:javax.servlet.ServletContext的实例,该实例代表JSP所属的web应用本身。可用于jsp页面、servlet之间交换信息。

config:javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息。事实上,JSP页面无须配置。该对象更多在servlet中有效。

page:代表页面本身,也就是Servlet中的this。

pageContext:javax.servlet.jsp.PageContext的实例,该对象代表该JSP页面上下文,使用该对象可以访问页面中的共享数据。

out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容,形成HTML页面。

request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象中。

response:javax.servlet.http.HttpServletResponse的实例,代表服务器对客户端的响应。通常很少使用该对象直接响应,而是使用out对象。

session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。

exception:java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当页面的page指令的isErrorPage属性为true时,才可使用exception对象。即只有异常处理页面对应Servlet时才会初始化exception对象。

 

web服务器接收到客户端连接请求后,使用单独的线程为该客户端提供服务:接收数据,返回数据。

web服务器负责完成多线程、网络通信等底层功能。web服务器必须为Servlet API中绝大部分接口提供实现类。

 

JSP、Servlet之间如何交换数据?——通过4个类似Map的结构application、session、request、page。

application:对整个web应用有效;放在application中的数据可以被该应用下其它所有的jsp、servlet访问;

session:仅对一次会话有效;

request:仅对本次请求有效;

page:仅对当前页面有效;

 

application对象(jsp中)代表web应用本身,对应于servlet中ServletContext对象,有两个作用:

a、在整个web应用的多个jsp、servlet之间共享数据;

b、访问web应用的配置参数;使用getInitParameter()获取web应用的配置参数,这些配置参数在web.xml中使用context-param元素配置。

 

javaee.jar文件添加到classpath环境变量中;若没有安装JAVA EE SDK,可将Tomcat中lib目录下的jsp-api.jar、servlet-api.jar两个文件添加到classpath环境变量中。

 

web.xml中使用<context-param>元素配置的参数对整个web应用有效。因此称为web应用的配置参数。

 

config对象代表当前jsp配置信息,是ServletConfig的实例。该对象在Jsp页面中很少用,但在servlet中用的多。因为servlet需要在web.xml中进行配置,可以指定配置参数。

用getInitParameter()来获取配置参数的方法。在web.xml中用<init-param>元素为servlet配置参数。

可以将Jsp当成servlet配置在web.xml中。只需将<servlet-name>元素换成<jsp-file>元素即可,其它不变。

 

在使用输出表达式的地方,都可以使用out对象达到同样效果。所有使用out的地方,都可使用输出表达式来代替,即<%=%>表达式的实质就是out.write();

 

通过pageContext可用于获取其它内置对象,如request对象、response对象、config对象、application对象、session对象。

 

服务器端负责解析请求头/请求参数的是jsp或servlet。一次请求总是包含若干请求头。POST发送的请求参数和值放在HEADER中传输。

有name属性的表单域才生成请求参数;若有多个表单域有相同的name属性,则多个表单域只生成一个请求参数,只是该参数有多个值。

 

POST:若发送请求的表单页采用gbk字符集,该表单页发送的请求也将采用gbk。因此使用request.setCharacterEncoding("gbk")进行解码; 

GET:为了获取GET请求里的中文参数值,必须借助于java.net.URLDecoder类。如:String queryStr =java.net.URLDecoder.decode(rawQueryStr, "gbk");

reqeust.getQueryString()获取请求里包含的查询字符串。

也可以在获取请求参数值之后对请求参数值重新编码,即先将其转换成字节数组,再将字节数组重新解码成字符串。如:

String rawName = request.getParameter("name");

byte[] rawBytes = rawName.getBytes("ISO-8859-1");

String name = new String(rawBytes, "gbk");

 

request有一个功能就是执行request和include。如:getRequestDispatcher("/a.jsp").include(request, response);//将a.jsp页面include到本页面中。

 

response响应生成非字符响应,如生成PDF文件、Excel文件、图片等;

重定向

增加cookie:session会随浏览器的关闭而失效,但cookie会一直存放在客户端机器上,直到超出cookie的生命期限。方法是addCookie(Cookie cookie);

创建Cookie:Cookie c = new Cookie("aa", "aa");

c.setMaxAge(24 * 3600);

response.addCookie(c);

 

访问Cookie,使用Request对象,提供了getCookie()方法,该方法返回客户端上所有Cookie组成的数组。

使用Cookie对象必须设置其生存期限,否则Cookie将会随浏览器的关闭而自动消失。

默认情况下,Cookie值不允许出现中文字符,若需要值为中文内容的Cookie,可以通过java.net.URLEncoder先对中文字符进行编码,将编码后的值设为Cookie值。当程序要读取Cookie时,先读取,然后使用java.net.URLDecoder对其进行解码。

如:Cookie c = new Cookie("name", java.net.URLEncoder.encode("孙武", "gbk"));

 

if(cookie.getName.equals("name")) {

       java.net.URLDecoder.decode(cookie.getValue());

}

 

一次用户会话:从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止。一旦关闭浏览器,即session结束。

 

session机制通常用于保存客户端的状态信息,这些状态信息需要保存到web服务器的硬盘上。因此要求session里的属性值必须是可序列化的。

 

servlet:

可以重写service()方法即可响应客户端的所有请求。

不需要为Servlet类编写构造器。

destroy()方法:销毁Servlet实例时,自动调用该方法的回收资源。

init()方法:初始化时自动调用此方法; 

 

servlet的创建以及销毁等由web容器进行控制的。

创建Servlet实例有两个时机:

a、客户端第一次请求某个servlet时,系统创建该servlet的实例。

b、web应用启动时立即创建servlet实例,即load-on-startup。其整型值越小,servlet就越先实例化。

每个servlet运行都遵循如下生命周期:

a、创建servlet实例;

b、web容器调用init()方法,对其进行初始化;

c、servlet将一直存在于容器中,用于响应客户端请求。.

d、web容器决定销毁servlet时,先调用其destroy方法。(通常是在关闭web应用时销毁servlet)

 

若没有为servlet配置URL,则该servlet不能响应用户请求。 

 

ServletConfig获取配置参数的方法和ServletContext获取配置参数的方法完全一样,只是ServletConfig是获取当前Servlet的配置参数,ServletContext是获取整个web应用的配置参数。

 

直接在页面上生成输出;

自定义标签库规范。但在JSP1.1规范中开发自定义标签库比较复杂,JSP2规范简化了标签库的开发。在JSP2中开发标签库需如下步骤:

重写doTag()方法用于生成页面内容。若标签类有属性,每个属性都有对应的getter和setter方法。(页面中标签填的属性值会自动赋给类中的属性的,属性名要一致!)    getJspContext().getOut()——获得页面输出流

每个tld文件对应一个标签库,每个标签库可包含多个标签;

c、在jsp页面中使用自定义标签;

tld文件放到WEB-INF/路径或WEB-INF的任意子路径下。web规范会自动加载该文件,该文件定义的标签库也将生效。

short-name:该标签库的默认短名;

uri:该标签库的唯一标识。JSP页面使用标签库时就是根据此URI属性来定位标签库的;

JSP2规范不再推荐使用JSP脚本,因此JSP2自定义标签的标签体中不能包含JSP脚本。

 

在JSP页面使用标签:

a、导入标签库;——使用taglib编译指令。

b、标签名:确定使用哪个标签。

 

如:

<tag>

        <name></name>              //定义标签名

        <tag-class></tag-class>          //标签处理类

        <body-content>empty</body-content>   //定义标签体为空

        <attribute>                 //标签属性

                   <name></name>     

                   <required></required>     //属性是否是必需的

                   <fragment></fragment>   //该属性是否支持JSP脚本、表达式等动态内容,值为true或false

        </attribute>

</tag>

 

JSTL是Sun提供的一套标签库;DisplayTag是Apache的一套标签库;

 

带标签体的标签:

getJspContext().getAttribute(属性名);——获取页面中属性名的值;

可输出标签体内容。

 

动态属性标签:

若需要传入自定义标签的属性个数是不确定的,属性名也不确定,就需要借助于动态属性标签了。

 

多了如下两个额外要求:

a、标签处理类还需要实现DynamicAttributes接口;必须要实现setDynaAttributes方法,该方法用于为该标签处理类动态添加属性名和属性值。

标签处理类使用ArrayList<String>类型的keys属性来保存标签的所有属性名,使用ArrayList<Object>类型的values属性来保存标签的所有属性值。

配置标签时通过<dynamic-attributes../>子元素指定该标签支持动态属性。

 

JSP2特性:

Servlet3.0对应于JSP2.2规范。

JSP2增加了如下特性:

配置JSP属性;——不常用;

b、表达式语言;

c、简化的自定义标签API;

d、Tag文件语法;

若要使用JSP2语法,则web.xml文件必须使用Servlet2.4以上版本的配置文件。

 

关于JSP的属性配置信息:

<jsp-config>

      <jsp-property-group>

                 <url-pattern></url-pattern>

                 <page-encoding></page-encoding>

                 <el-ignored></el-ignored>

      </jsp-property-group>

</jsp-config>

 

简化的数据访问方式。可以方便访问JSP的隐含对象和JavaBeans组件。在JSP2规范中,建议尽量使用表达式语言,避免使用java脚本。

语法格式:$(expression)

若需要在支持表达式语言的页面中正常输出$符号,可以在$符号前加转义字符“\”。

 

内置对象:可以获取请求参数值、获取页面中JavaBean的指定属性值、获取请求头及获取page、request、session、application范围的属性值等。

pageContext:代表该页面的pageContext对象。

pageScope:用于获取page范围的属性值;

requestScope:用于获取request范围的属性值;

sessionScope:用于获取session范围的属性值;

applicationScope:用于获取application范围的属性值;

param:用于获取请求的参数值;

paramValues:该对象用于获取属性值为数组的属性值;

header:用于获取请求头的属性值;

headerValues:该对象用于获取属性值为数组的属性值;

initParam:用于获取请求web应用的初始化参数;

cookie:用于获取指定的Cookie值;

如:value="${param['name']}"或value="${param.name}"

 

允许在EL中调用某个类的静态方法。

 

Tag File:是自定义标签的简化用法。使用TagFile可以不需要定义标签处理类和标签库文件,但仍然可以在JSP页面中使用自定义标签。

建立Tag文件:在JSP所支持TagFile规范下,TagFile代表了标签处理类。

Tag File的主文件名就是标签名。该文件必须存在web应用的某个路径下,该路径相当于标签库的URI名。如/WEB-INF/tags下。

 

每个Tag File对应一个标签。

 

伴随JavaEE6一起发布的Servlet3.0规范,简化了java web应用的开发。

组件(如servlet、filter、listener)都部署在web.xml文件中,允许采用web模块来部署、管理它们。

 

Servlet3.0提供异步处理:

servlet必须等到业务方法完全返回之后才生成响应。 

重新发起一条新线程去调用耗时的业务方法,避免等待。

开启异步调用、创建AsyncContext对象。

a、startAsync();

b、startAsync(ServletRequest, ServletResponse);

被异步请求dispatch的目标页面需要指定session="false",表明该页面不会重新创建session。

开发者必须显式指定开启异步调用。在web.xml中的<servlet>元素中增加<async-supported>子元素。

 

对于支持异步调用的Servlet来说,当servlet以异步方式启用新线程之后,该servlet的执行不会被阻塞,该servlet将可以向客户端浏览器生成响应——当新线程执行完成后,新线程生成的响应再次被送往客户端浏览器。

 

Servlet3.0规范也完全支持在Filter中使用异步调用。因为Filter与Servlet具有很大的相似性。

 

改进的Servlet API:简化了Java Web开发。

有两个较大的改进:

a、HttpServletRequest增加了对文件上传的支持;提供了两个方法处理文件上传:getPart(String name)——根据名称来获取文件上传域;getParts()——获取所有的文件上传域;

b、ServletContext允许通过编程的方式动态注册Servlet、Filter;

 

每个Part对象对应一个文件上传域,该对象提供大量方法来访问上传文件的文件类型、大小、输入流等。并提供write(String file)方法将上传文件写入服务器磁盘。

文件域,此外还要为表单域设置enctype属性,值为multipart/form-data。

对于传统的文件上传需要借助于common-fileupload等工具。可以借助于Servlet3.0的API,处理文件上传较简单。

处理文件上传的servlet需要在web.xml中的<servlet>元素中添加<multipart-config>子元素。

 

java.util.UUID工具类生成文件名,为了防止重复。

 

ServletContext提供了如下方法来动态注册Servlet、Filter,并允许动态设置web应用的初始化参数。

a、addServlet()——动态注册Servlet

b、addFilter()——动态注册Filter

c、addListener()——动态注册Listener

d、setInitParameter(String name, String value)——为web应用设置初始化参数

 

(2)Filter

对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。可认为是servlet的一种加强版。

 

创建Filter:

a、创建Filter处理类,必须实现javax.servlet.Filter接口。

b、在web.xml中配置Filter;

 

分界线为是否调用了chain.doFilter(),执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。 

 

Java filter多个条件_java

Filter和Servlet具有完全相同的生命周期行为,Filter也可通过<init-param/>元素来配置初始化参数,获取Filter的初始化参数可使用FilterConfig的getInitParameter()方法。

 

(3)Listener

web应用内部会不断发生各种事件:如web应用被启动、web应用被停止,用户session开始、用户session结束、用户请求到达等。 

当web内部事件发生时回调事件监听器内的方法。

 

创建Listener:

a、定义Listener实现类;

b、在web.xml中配置Listener。

 

常用的web事件监听器接口有如下几个:

启动和关闭;

b、ServletContextAttributeListener:用于监听ServletContext范围内属性的改变;

c、ServletRequestListener:用于监听用户请求;

d、ServletRequestAttributeListener:用于监听ServletRequest范围内属性的改变;

e、HttpSessionListener:用于监听用户session的开始和结束。

f、HttpSessionAttributeListener:用于监听HttpSession范围内属性的改变;

 

 

2、TIPS

(1)业务逻辑组件:实现系统的业务逻辑。

业务逻辑方法仅仅负责实现业务逻辑,不应该进行数据库访问。

业务逻辑组件中不要出现原始的Hibernate、JDBC等API。

 

Domain Object)

系统的对象模型。每个领域对象通常对应一个或多个数据表。

 

(3)服务器

Jetty:可作为一个嵌入式服务器,即若在应用中加入Jetty的jar文件,应用可在代码中对外提供web服务。

Resin:目前最快的jsp、servlet运行平台,支持EJB。

 

JavaEE服务器,如开源的Jboss和商用的WebLogic、WebSphere,支持更多的JavaEE特性,如分布式事务、EJB容器等。

 

对于每次客户端请求而言,web服务器需要完成以下几个步骤:

a、启动单独线程;

b、使用IO流读取用户的请求数据;

c、从请求数据中解析参数;

处理用户请求;

e、生成响应数据

f、使用IO流,向客户端发送响应数据

 

(4)浏览器

大部分浏览器通常负责完成三件事:

a、发送请求;

b、读取服务器返回的字符串数据;

c、负责根据字符串数据渲染出页面;

 

(5)Tomcat

其中的wrok目录:保存web应用运行过程中,编译生成的class文件。

 

运行Tomcat只需要一个环境变量:JAVA_HOME。该环境变量的值指向JDK安装路径。

 

多个端口提供服务:

 复制server.xml中的<Service>元素,并修改相应参数就可以实现一个Tomcat运行多个服务。

 

让Tomcat列出web应用根路径下的所有页面,可以打开Tomcat的conf目录下的web.xml文件,修改:

<init-param>

           <param-name>listings</param-name>

true</param-value>

</init-param>

 

控制台的用户名和密码是通过Tomcat的JAAS控制的。

JAAS(java验证和授权API):它用于控制对java web应用的授权访问。

在web.xml中,通过<security-constraint>元素确定访问某某资源需要某某角色。通过<login-config>元素确定JAAS的登录方式。

Tomcat默认采用文件安全域,即以文件存放用户名和密码。Tomcat的用户由conf目录下tomcat-users.xml文件控制。在其中定义角色,定义用户等。

 

好处是不需要将web应用复制到Tomcat下。

 

内置了DBCP的数据源实现,可以方便的配置。

Tomcat提供了两种配置数据源的方式,一种可以让所有的web应用都访问,一种只能在单个的web应用中访问。局部数据源只需修改web应用的配置文件,全局数据源需要修改Tomcat的server.xml文件。

 

就是为某个java对象取了一个名字,从而让程序可以通过此名字来访问。

Tomcat提供的JNDI绑定必须加前缀:java:comp/env。

 

(6)Eclipse

Eclipse插件的安装方式有:

a、在线安装

help——install new software。

更新。

 

点击add进行安装新插件,name中输入插件名,Location中输入插件的安装地址(Eclipse插件的安装地址需要从各插件的官方站点上查询)。

也可以点击archive...按钮,这样可以从本地压缩包安装插件。

 

b、手动安装

直接安装(不建议)和扩展安装。

扩展安装使得每个插件都放在单独的文件夹内,若要卸载某个插件,只需将该插件对应的link文件删除即可。

 

开发web应用步骤:

配置web服务器。

在eclipse下方面板servers的空白处,单击在弹出的快捷菜单中选择“new-server”

选择Dynamic web project。

部署web应用可单击eclipse左边导航,run as——run on server选项。

启动指定的web服务器。

 

分别导入指定文件的方式。

a、新建一个普通的eclipse项目

b、单击file——import,选择file system。输入需要导入文件的路径,选中需要导入的文件,并输入需要导入到eclipse项目的哪个目录下即可。

 

还有一种方式:直接进入需要被导入的项目路径下,将相应的文件复制到eclipse项目的相应路径下即可。

 

(7)URL Rewrite开源项目

a、登陆http://www.tuckey.org/urlrewrite站点下载URL Rewrite,应下载src项,即urlrewritefilter-3.2.0-src.zip。

b、在web.xml中配置启用URL Rewrite Filter。如:

<filter>

       <filter-name>UrlRewriteFilter</filer-name>

       <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>

<filter>

<filter-mapping>

       <filter-name>UrlRewriteFilter</filter-name>

       <url-pattern>/*</url-pattern>

</filter-mapping>

c、在WEB-INF路径下增加urlrewrite.xml文件,该文件定义了伪静态映射规则,这份伪静态规则是基于正则表达式的。

 

Java filter多个条件_Java filter多个条件_02

上面的规则文件中只定义了一个简单的规则:所有发向/userinf-(\w*).html的请求都将被forward盗user.jsp页面,并将(\w*)正则表达式所匹配的内容作为username参数值。

 

(8)

 

 

3、PS

分层:

层与层之间以松耦合的方法组织在一起。

 

(2)DAO:对数据库的CRUD操作。

EAO:对实体的CRUD操作。

 

业务逻辑层由EJB充当。

 

传统快速应用开发理念。

Tapestry同时提供了控制器和页面模板的解决方案,使用Tapestry无须使用Jsp等其它表现层技术。

 

JPA规范是一种ORM规范。它的底层可以使用hibernate等任意一种ORM框架作为实现。