目录

1. J2EE简介
2. JAVA EE应用的分层模型
3. 搭建Struts2 Demo应用
4. struts2流程
5. struts2的常规配置
6. 实现Action
7. 配置Action
8. 配置处理结果
9. 配置struts2的异常处理
10. convention插件与"约定"支持
11. 使用struts2的国际化
12. 使用struts2的标签库

 

1. J2EE简介

0x1: JavaBeans

JavaBeans是Java语言中可以重复使用的软件组件,它们是一种特殊的Java类,将很多的对象封装到了一个对象(bean)中。特点是

1. 可序列化
2. 提供无参构造器
3. 提供getter方法和setter方法访问对象的属性
4. Bean可以控制它的属性、事件和方法是否暴露给其他程序
5. Bean可以接收来自其他对象的事件,也可以产生事件给其他对象
6. 有软件可用来配置Bean
7. Bean的属性可以被序列化,以供日后重用

javabeans从本质上来讲是一个规范性的概念,要成为JavaBean类,则必须遵循关于命名、构造器、方法的特定规范。有了这些规范,才能有可以使用、复用、替代和连接JavaBeans的工具。反过来说,如果一个java类满足了这些规范,就可以称之为javabeans

package player;
 
public class PersonBean implements java.io.Serializable {
 
    /**
     * name 属性(注意大小写)
     */
    private String name = null;
 
    private boolean deceased = false;
 
    /** 无参构造器(没有参数) */
    public PersonBean() {
    }
 
    /**
     * name 属性的Getter方法
     */
    public String getName() {
        return name;
    }
 
    /**
     * name 属性的Setter方法
     * @param value
     */
    public void setName(final String value) {
        name = value;
    }
 
    /**
     * deceased 属性的Getter方法
     * 布尔型属性的Getter方法的不同形式(这里使用了is而非get)
     */
    public boolean isDeceased() {
        return deceased;
    }
 
    /**
     * deceased 属性的Setter方法
     * @param value
     */
    public void setDeceased(final boolean value) {
        deceased = value;
    }
}

TestPersonBean.java:

import player.PersonBean;
 
/**
 * <code>TestPersonBean</code>类
 */
public class TestPersonBean {
    /**
     * PersonBean 类测试方法的main函数
     * @param ARGS
     */
    public static void main(String[] args) {
        PersonBean person = new PersonBean();
 
        person.setName("张三");
        person.setDeceased(false);
 
        // 输出: "张三[活着]"
        System.out.print(person.getName());
        System.out.println(person.isDeceased() ? " [已故]" : " [活着]");
    }
}

testPersonBean.jsp

<% // 在JSP中使用PersonBean类 %>
<jsp:useBean id="person" class="player.PersonBean" scope="page"/>
<jsp:setProperty name="person" property="*"/>
 
<html>
    <body>
        姓名:<jsp:getProperty name="person" property="name"/><br/>
        已故与否?<jsp:getProperty name="person" property="deceased"/><br/>
        <br/>
        <form name="beanTest" method="POST" action="testPersonBean.jsp">
            输入姓名:<input type="text" name="name" size="50"><br/>
            选择选项:
            <select name="deceased">
                <option value="false">活着</option>
                <option value="true">已故</option>
            </select>
            <input type="submit" value="测试这个JavaBean">
        </form>
    </body>
</html>

虽然JavaBean和Java之间已经有了明确的界限,但是在某些方面JavaBean和Java之间仍然存在很容易混淆的地方,比如说重用,Java语言也可以为用户创建可重用的对象,但它没有管理这些对象相互作用的规则或标准,用户可以使用在Java中预先建立好的对象,但这必须具有对象在代码层次上的接口的丰富知识。而对于JavaBean,用户可以在应用程序构造器工具中使用各种JavaBean组件,而不需要编写任何代码。这种同时使用多个组件而不考虑其初始化情况的功能是对当前Java模型的重要扩展,所以也可以说JavaBean是在组件技术上对Java语言的扩展
如果真的要明确的定义,那么JavaBean的定义是:JavaBean是可复用的平台独立的软件组件,开发者可以在软件构造器工具中对其直接进行可视化操作

Relevant Link:

http://zh.wikipedia.org/wiki/JavaBeans
http://eduunix.ccut.edu.cn/index2/edu/%C7%E5%BB%AA%B4%F3%D1%A7%BC%C6%CB%E3%BB%FA%BF%CE%B3%CC/JAVA%B1%E0%B3%CC%D3%EF%D1%D4/text/ch09/se01/9_1_2.htm

0x2: POJO(pure old java object)

关于POJO,我们首先明确一句话

A JavaBean is a POJO that is serializable, has a no-argument constructor, and allows access to properties using getter and setter methods that follow a simple naming convention.

POJO(pure old java object)是普通java类,有一些private的参数作为对象的属性,然后针对每一个参数定义get和set方法访问的接口。仅此而已,不能有别的更多的动作了

POJO其实是比javabean更纯净的简单类或接口。POJO严格地遵守简单对象的概念,而一些JavaBean中往往会封装一些简单逻辑。
JavaBean是一种JAVA语言写成的可重用组件。它的方法命名,构造及行为必须符合特定的约定:

1.这个类必须有一个公共的缺省构造函数
2.这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范
3.这个类应是可序列化的

简而言之,当一个POJO可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,它就是一个JavaBean

Relevant Link:

http://en.wikipedia.org/wiki/Plain_Old_Java_Object
http://my.oschina.net/pacoyang/blog/151695

0x3: SSH与EJB区别

EJB是一种javabean的组合规范,SSH是3个框架jar包的组合。
EJB本身是JavaEE的规范由容器厂商负责实现,也就是使用EJB,需要使用JavaEE服务器。而用SSH,直接用Web服务器, SSH中要解决的目标和EJB是一致的。EJB是大型的,SSH是轻量级的。

Relevant Link:

http://blog.csdn.net/jojo52013145/article/details/5783677

 

2. JAVA EE应用的分层模型

0x1: Struts 2简介

Struts 2由传统的Struts 1、webwork两个经典MVC框架发展起来,与传统的Struts 1相比

1. Struts 2允许使用普通的、传统的java对象作为action
2. action的execute()方法不再与servlet api耦合,因而更易测试
3. 支持更多的视图技术
4. 基于AOP(Aspect-Oriented Programming)思想的拦截器机制,提供了更好的可扩展性
5. 更强大、更易用的输入校验功能
6. 整合的ajax支持
...

0x2: MVC简介

MVC思想将一个应用分成三个基本部分,这三个部分以最小的耦合协同工作,从而提高应用的可扩展性及可维护性

1. Model(模型)
2. View(视图)
3. Controller(控制器)

在经典的MVC模式中,事件由控制器处理,控制器根据事件的类型改变模型或视图,每个模型对应一系列的视图列表,这种对应关系通常采用注册来完成,即:把多个视图注册到同一个模型,当模型发生改变时,模型向所有注册过的视图发送通知,接下来,视图从对应的模型中获得信息,然后完成视图显示的更新
概括起来,MVC有如下特点

1. 多个视图可以对应同一个模型,可以减少代码的复制及代码的维护量,一旦模型发生改变,也易于维护
2. 模型返回的数据与显示逻辑分离。模型数据可以应用任何的显示技术
    1) JSP页面
    2) Velocity模版
    3) Excel文档
3. 应用被分隔为三层,降低了各层之间的耦合,提供了应用的可扩展性
4. 控制层的概念也很有效,由于它把不同的模型和不同的视图组合在一起,完成不同的请求。因此,控制层可以说是包含了用户请求权限的概念
5. MVC更符合软件工程化管理的思想。不同的层各司其职,每一层的组件具有相同的特征,有利于通过工程化和工具化产生管理程序代码

MVC思想将应用中各组件按功能进行分类,不同的组件使用不同技术充当,甚至推荐了严格分层,不同组件被严格限制在其所在层内,各层之间以松耦合的方式组织在一起,从而提供了良好的封装

Struts 2 Learning

0x3: Domain Object(领域对象)

此层由系列的POJO(Plain Old Java Object,普通的、传统的Java对象)组成,这些对象是该系统的Domain Object,往往包含了各自所需要实现的业务逻辑方法

0x4: DAO(Data Acess Object 数据访问对象)

此层由系列的DAO组件组成,这些DAO实现了对数据库的创建、查询、更新和删除(CRUD)等原子操作。
在经典Java EE应用中,DAO层也被改称为EAO层,EAO层组件的作用与DAO层组件的作用基本相似。只是EAO层主要完成对实体(Entity)的CRUD操作,因此简称为EAO层

0x5: PO(persistant object 持久对象)

持久对象,可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作.

0x6: VO(value object 值对象)

通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要。

0x7: DTO(data access object 数据访问对象)

此对象用于访问数据库。通常和PO结合使用,DAO中包含了各种数据库的操作方法。通过它的方法,结合PO对数据库进行相关的操作

我们通过DAO将POJO持久化为PO,用PO组装出来VO、DTO

0x8: BO(business object 业务对象)

封装业务逻辑的java对象,通过调用DAO方法,结合PO、VO进行业务操作

Relevant Link:

http://www.oecp.cn/hi/yongtree/blog/122
http://blog.sina.com.cn/s/blog_9af0d32b0101030l.html
http://my.oschina.net/pacoyang/blog/151695
http://www.cnblogs.com/xiaoluojava/archive/2010/05/07/1729992.html

 

3. 搭建Struts2 Demo应用

0x1: 创建web应用

为了让web应用具有struts 2支持功能,必须将struts 2框架的核心类库(JAR包)增加到web应用中
/HelloWorldStruts2/WebContent/WEB-INF/lib

commons-fileupload-1.3.1.jar
commons-io-2.2.jar
commons-lang-2.4.jar
commons-lang3-3.2.jar
commons-logging-1.1.3.jar
commons-logging-api-1.1.jar
freemarker-2.3.22.jar
javassist-3.11.0.GA.jar
ognl-3.0.6.jar
struts2-core-2.3.24.jar
xwork-core-2.3.24.jar

0x2: web.xml
通常,所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts2框架而言,需要加载FilterDispatcher,只要Web应用负责加载FilterDispatcher,FilterDispatcher将会加载Struts2框架,因为Struts2将核心控制器设计成Filter,而不是一个普通Servlet。故为了让Web应用加载FilterDispatcher,只需要在web.xml文件中配置FilterDispatcher即可
/HelloWorldStruts2/WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
   
   <display-name>Struts 2</display-name>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterorg.apache.struts2.dispatcher.FilterDispatcher</filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

从本质上讲,struts2并不是一个新的东西,struts2是基于J2EE框架上的一层封装,使开发者更容易地进行J2EE的开发,struts2是一个MVC开发框架,从逻辑上位于spring、hibernate的上层
我们知道,以上配置仅仅修改了web.xml文件仅仅完成了为web应用增加struts2支持,而struts2是基于过滤器实现的,要使用strucs2功能至少还需要一个struts.xml文件

0x3: struts.xml

/HelloWorldStruts2/WebContent/WEB-INF/classes/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
   <package name="helloworld" extends="struts-default">
      <action name="hello" class="com.tutorialspoint.struts2.HelloWorldAction" method="execute">
            <result name="success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

0x4: index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
   <h1>Hello World From Struts2</h1>
   <form action="hello">
      <label for="name">Please enter your name</label><br/>
      <input type="text" name="name"/>
      <input type="submit" value="Say Hello"/>
   </form>
</body>
</html>

J2EE struts2采用了充分的面向对向、封装、解耦的设计,将后端的处理逻辑全部放到了javabeans实现,而将前台的展示由JSP实现,JSP和javabeans之间的纽带通过action实现,所有的用于处理后端业务逻辑的javabeans都继承了ActionSupport类
/HelloWorldStruts2/src/com.tutorialspoint.struts2

package com.tutorialspoint.struts2;

public class HelloWorldAction
{
       private String name;

       public String execute() throws Exception 
       {
          return "success";
       }
       
       public String getName() 
       {
          return name;
       }

       public void setName(String name) 
       {
          this.name = name;
       }
}

0x5: HelloWorld.jsp

如果execute方法返回"success", 然后我们把用户引到HelloWorld.jsp
/HelloWorldStruts2/WebContent/HelloWorld.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
   Hello World, <s:property value="name"/>
</body>
</html>

Struts 2 Learning

Relevant Link:

http://www.yiibai.com/struts2/struts2_examples.html
http://blog.csdn.net/xiazdong/article/details/7214967
http://www.360doc.com/content/11/0519/08/987036_117818681.shtml

 

4. struts2流程

0x1: struts2应用开发步骤

梳理一下struts2应用的开发步骤

1. 在web.xml文件中定义核心filter来拦截用户请求
由于web应用是基于请求/响应架构的应用,所以不管哪个MVC web框架,都需要在web.xml中配置该框架的核心filter或servlet,这样才可以让框架介入web应用中
/*
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterorg.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
*/

2. 如果需要以POST方式提交请求,则定义包含表单数据的JSP页面,如果仅仅只是以GET方式发送请求,则无须经过这一步
3. 定义处理用户请求的Action类
这一步是所有MVC框架中必不可少的,因为这个Actino就是MVC中的C,即控制层,该控制器负责调用Model里的方法来处理请求
/*
MVC框架的底层机制是,核心servlet或filter接收到用户请求后,通常会对用户请求进行简单预处理,例如解析、封装参数等,然后通过反射来创建Action实例,并调用Action的指定方法来处理用户请求,这就产生了一个问题: 当servlet或filter拦截用户请求后,它应该如何知道创建哪个Action的实例
    1) 利用配置文件
    2) 利用约定
*/

4. 我们知道,在MVC框架中,控制器实际上由2个部分共同组成
    1) 即拦截所有用户请求,处理请求的通用代码都由核心控制器完成
    2) 实际的业务控制(诸如调用model,返回处理结果等),则由Action处理

5. 配置Action
对于java领域的大部分MVC框架而言,都经常使用XML文件来配置管理,配置Action就是指定哪个请求对应哪个Action进行处理,从而让核心控制器根据该配置来创建合适的Action实例,并调用该Action的业务控制方法,例如
/*
<action name="hello" class="com.tutorialspoint.struts2.HelloWorldAction" method="execute">
    <result name="success">/HelloWorld.jsp</result>
</action>
指定了如果用户请求URL为login,则使用com.tutorialspoint.struts2.HelloWorldAction来处理,值得注意的是,struts2的convention插件借鉴了Rails框架的优点,开始支持"约定优于配置"的思想,也就是采用约定方式来规定用户请求地址和Action之间的对应关系
*/

6. 配置处理结果和物理视图资源之间的对应关系
当Action处理用户请求结束后,通常会返回一个处理结果(简单字符串),我们可以认为该名称是逻辑视图名,这个逻辑视图名需要和指定物理视图进行关联
/*
<action name="hello" class="com.tutorialspoint.struts2.HelloWorldAction" method="execute">
    <result name="success">/welcome.jsp</result>
    <result name="input">/login.jsp</result>
    <result name="error">/error.jsp</result>
</action>
*/

7. 编写视图资源,如果Action需要把一些数据传给视图资源,则可以借助于OGNL表达式

0x2: struts2的流程

Struts 2 Learning

相关文章: