3.[Struts2權威指南筆記]整合Spring

1.Struts2插件

Struts2通過提供各種插件,用於與大部分流程的J2EE框架進行整合。

插件概述

Struts2的插件是一個JAR文件,這個JAR文件可以用於擴展、改變或者添加Struts2的功能。每個Struts2的插件JAR都包含一個名爲struts-plugin.xml的配置文件,struts-plugin.xml文件的內容與普通的struts.xml文件內容完全相同。

當把這個包含struts-plugin.xml文件的JAR文件複製到Web應用中時,Struts2會自動加載該JAR文件的struts-plugin.xml文件。

Struts2應用包含3種類型的配置文件:struts-default.xml(包含在struts2-core.xml文件中),struts-plugin.xml(包含在各插件JAR文件中)和struts.xml文件。

啓動一個struts2應用時,加載順序: struts-default.xml、struts-plugin.xml和struts.xml。

2.集成Spring

和Spring集成的目標:是希望Struts2的Action定義直接使用Spring IoC的功能,將業務層的Bean注入到Struts的Action中。

將Struts類包添加到lib路徑下

struts2-core.2.jar

xwork-2.jar

ognl-2.jar

struts2-spring-plugin-2.jar

freemarker-2.jar

其中struts2-spring-plugin-2.jar就是將Struts2集成到Spring中的類包,該類包有一個struts-plugin.xml配置文件,定義了一個名爲spring的StrutsSpringObjectFactory的Bean,以便將Action類的管理工作委託給Spring容器進行。

編寫Struts配置文件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>
    <!-- 通過這個配置指定使用struts-plugin.xml中的StrutsSpringObjectFacotry作爲創建Action的工具類 -->
    <constant name="struts.objectFactory" value="spring" />
</struts>

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" 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">
    <!-- spring config -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:ApplicationContext*.xml</param-value>
    </context-param>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 定義Struts2的核心控制器FilterDispathcer的Filter -->
    <filter>
        <!-- 定義核心Filter的名字 -->
        <filter-name>struts2</filter-name>
        <!-- 定義核心Filter的實現類 -->
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <!-- FilterDispatcher用來初始化struts2並且處理所有的HTTP請求。 -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <!-- 定義struts2.0 end.  -->
</web-app>

通過contextConfigLocation指定Spring配置文件,並配置ContextLoaderListener啓動Spring容器。

整合流程

Struts2的核心控制器是攔截用戶請求,然後將請求轉發給對應Action處理,這個過程是固定的。但實際上,Action實例是由Spring容器產生,而不是Struts2容器,Spring通過提供一種僞Action,當在struts.xml文件配置Action時,通常需要指定class屬性,不是指向Action的實際類,而是指向Spring容器的Bean ID。

在整合策略下,處理用戶請求的Action有Spring負責創建,但Spring創建Action實例時,並不是利用配置Action時指定的class屬性來創建該Action實例,而是從Spring容器中取出對應的Bean實例完成創建。

3.註冊用戶實例

創建Action對象

public class User {
    private String userName;
    private String password;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
import cms.com.system.domain.User;
import com.opensymphony.xwork2.ActionSupport;
public class UserRegisterAction extends ActionSupport {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public String execute() throws Exception {
        if(user == null) {
            user = new User();
            return "input";
        } else {
            return "success";
        }
    }
}

配置Action

在ApplicationContext.xml的Spring配置文件中配置UserRegisterAction Bean:

<bean id="registerUserAction" class="cms.com.system.action.UserRegisterAction" scope="prototype" />

在Spring中配置好Struts2的Action,在Struts配置文件中引用這個Bean:

<?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>
    <!-- 通過這個配置指定使用struts-plugin.xml中的StrutsSpringObjectFacotry作爲創建Action的工具類 -->
    <constant name="struts.objectFactory" value="spring" />
    <!-- struts2的Action都必須配置在package裏 -->
    <package name="user" extends="struts-default">
        <action name="registerUserAction" class="registerUserAction">
            <result name="input">/jsp/registerUser.jsp</result>
            <result name="success">/jsp/success.jsp</result>
        </action>
    </package>
</struts>

其中class="registerUserAciton",在正常情況下,struts通過class屬性指定Action給的實現類:

<action name="registeruserAction" class="cms.com.system.action.UserRegisterAction">

但此時卻是一個類似於Bean名的字符串,事實上class屬性的值正是指向Spring容器中的Bean名稱,在後臺通過StrutsSpringObjectFactory獲得真實的Action實例。

當使用Spring容器管理系統的Action,在struts.xml文件中配置該Action時,class屬性並不是指向Action實體類,而是指向了Spring容器中Action的實例的ID。

表單頁面和成功頁面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title>My JSP 'MyJsp.jsp' starting page</title>
  </head>
  <body>
    <s:form>
        <s:textfield key="user.userName" label="用戶名" />
        <s:textfield key="user.password" label="密碼" />
        <s:submit/>
    </s:form>
  </body>
</html>

表單標籤<s:form>通過簡單地標籤聲明,無需通過action屬性指定表單提交地址,表單組件標籤也通過級聯屬性的方式綁定表單對象。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title>My JSP 'MyJsp.jsp' starting page</title>
  </head>
  <body>
    <s:form>
        <s:textfield key="user.userName" label="用戶名" />
        <s:textfield key="user.password" label="密碼" />
        <s:submit/>
    </s:form>
  </body>
</html>

測試用戶註冊界面

在點擊Submit提交表單後,RegisterUserAction負責處理表單提交,處理後將重定向到success.jsp頁面上。

完成Spring和Struts2的整合主要作用,是能讓Struts2的Action實例利用Spring容器的IoC特性。

整合的不足

Spring管理Action,必須將所有的Action配置在Spring容器中,而struts.xml未見還需要配置一個“僞Action”,從而導致文件臃腫、冗餘。

Action的業務邏輯組件接收容器注入,會導致代碼的可讀性降低。



說明:筆記內容摘自《Struts2權威指南》

關聯:整理了一些Java軟件工程師的基礎知識點



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章