关于Spring、Struts2与Ext的整合

【允许转载!但请注明出处!】

 

近日闲来无事研究了一下Struts2,并尝试将其与Spring和Ext整合在了一起。整合的时候遇到了不少麻烦,经过一顿折腾,终于成功完成了下面这个简单的小例子。

 

新建一个WEB项目,将Struts2的相应jar包添加到web-inf下的lib目录中。我用到的jar包包括antlr-2.7.2.jar、commons-fileupload-1.2.1.jar、commons-logging-1.0.4.jar、freemarker-2.3.15.jar、ognl-2.7.3.jar、struts2-core-2.1.8.jar和xwork-core-2.1.6.jar。因为要与Spring进行整合,所以将struts2-spring-plugin-2.1.8.jar及spring.jar也一并添加进去。然后添加对Spring的支持。本例子使用了ibatis操作Oracle数据库,需要导入ojdbc14.jar、ibatis-2.3.4.726.jar及两个Apach的jar:commons-dbcp.jar、commons-pool.jar。使用json数据返回ext前台需要添加struts2-json-plugin-2.1.8.jar的支持。

 

修改web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <listener>  
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
 </listener>  
  <display-name>Struts 2.0 Hello World</display-name>
 <!-- 定义Struts 2的FilterDispatcher的Filter -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <!-- FilterDispatcher用来初始化Struts 2并且处理所有的Web请求 -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping> 
   <welcome-file-list>
     <welcome-file>index.html</welcome-file>
   </welcome-file-list>
   <!-- 指定spring配置文件 -->
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/applicationContext.xml,
   /WEB-INF/*service.xml,
   /WEB-INF/dao/*dao.xml   
  </param-value>
 </context-param>
</web-app>

 

在WEB-INF下添加Service.xml:

<?xml version="1.0" encoding="GBK"?>

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
 <bean id="loginService" class="service.LoginServiceImpl">
 <!--  <property name="loginDao" ref="loginDao"></property> -->
 </bean>
 
 <bean id="helloWorldService" class="service.HelloWorldServiceImpl">
  <property name="loginDao" ref="loginDao"></property>
 </bean>
</beans>

 

在WEB-INF下新建dao文件夹,并在dao下添加dao.xml和sql-map-config.xml

dao.xml文件如下:

<?xml version="1.0" encoding="GBK"?>

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

   <bean id="abstractDao" abstract="true">
    <property name="sqlMapClient" ref="sqlMapClient"/>
   </bean>
 <bean id="loginDao" class="dao.LoginDao" parent="abstractDao"></bean>
</beans>

sql-map-config.xml文件如下:

<?xml version="1.0" encoding="GBK" ?>

<!DOCTYPE sqlMapConfig
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <settings lazyLoadingEnabled="true" useStatementNamespaces="true" />
    <sqlMap resource="dao/maps/TB_USER_SqlMap.xml"/>
</sqlMapConfig>

 

修改applicationContext.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans
 xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <description>加载属性文件列表</description>
  <property name="locations">
   <list>
    <value>WEB-INF/jdbc.properties</value>
   </list>
  </property>
 </bean>

 <!-- 需导入commons-dbcp.jar、commons-pool.jar和连接数据库的包 -->
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
 </bean>
 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <description>加载ibatis</description>
  <property name="configLocation" value="WEB-INF/dao/sql-map-config.xml"></property>
  <property name="dataSource" ref="dataSource"></property>
 </bean>
 
 <bean id="HelloWorldAction" class="tutorial.HelloWorld" >
  <property name="helloWorldService">
      <ref bean="helloWorldService"/>
    </property>
 </bean>
 

在WEB-INF下添加jdbc.properties文件

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:ljlei/ljlei@localhost:1521:orcl
jdbc.username=ljlei
jdbc.password=ljlei

 

在src下添加struts2的配置文件 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>
 <!-- 指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 -->
 <constant name="struts.i18n.encoding" value="UTF-8" />

 <include file="struts-default.xml" />
 <!-- Struts 2的Action必须放在指定的包空间下定义 -->
    <!-- <package name="tutorial" extends="struts-default"> -->
   <package name="tutorial" namespace="/" extends="json-default">
     <interceptors>
            <interceptor name ="auth" class ="tutorial.AuthorizationInterceptor" />
        </interceptors>
        <action name="HelloWorld" class="HelloWorldAction">
           <result type="json" />
       <!--
         <result name="login">SayHello.jsp</result>
            <result name="error">errorPage.jsp</result>
            <result name="success">HelloWorld.jsp</result>
        -->       
        </action>
        
    </package>   
</struts>

 

配置文件完成后,添加相应的java类文件

在src下新建HelloWorld.java

package tutorial;

import java.text.DateFormat;
import java.util.Date;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import service.HelloWorldService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import domain.User;

public class HelloWorld extends ActionSupport {
 private User user;
 private String message;
 private boolean success;
 private HelloWorldService helloWorldService;
 
 
 public boolean isSuccess() {
  return success;
 }

 public void setSuccess(boolean success) {
  this.success = success;
 }

 public HelloWorldService getHelloWorldService() {
  return helloWorldService;
 }

 public void setHelloWorldService(HelloWorldService helloWorldService) {
  this.helloWorldService = helloWorldService;
 }

 public User getUser() {
  return user;
 }

 public void setUser(User user) {
  this.user = user;
 }

 public String getMessage() {
  return message;
 }

 public void setMessage(String message) {
  this.message = message;
 }


 @Override
 public String execute() throws Exception{
  System.out.println(user.getUsername()+"---"+user.getPassword());  
  HttpServletRequest request = ServletActionContext.getRequest();
  HttpServletResponse response = ServletActionContext.getResponse();
  response.setContentType("text/html;charset=utf-8");
  if(helloWorldService.check(user)){
   String jsonString = "{success:true,msg:'验证成功!'}";
   System.out.println(jsonString);
   response.getWriter().print(jsonString);
   return null;
  }else {
   String jsonString = "{success:false,errors:'账户密码验证失败'}";
   System.out.println(jsonString);
   response.getWriter().print(jsonString);
   return null;
  }
 } 
 public String aliasAction(){
  message = "自定义Action调用方法";
  return SUCCESS;
 } 
}

 

 在src下新建HelloWorldService.java和HelloWorldServiceImpl.java

package service;

import domain.User;

public interface HelloWorldService {
 public boolean check(User user);
}

package service;

import tutorial.StringUtil;
import dao.LoginDao;
import domain.User;

public class HelloWorldServiceImpl implements HelloWorldService {
 private LoginDao loginDao;
 
 public LoginDao getLoginDao() {
  return loginDao;
 }

 public void setLoginDao(LoginDao loginDao) {
  this.loginDao = loginDao;
 }

 public boolean check(User user) {
  System.out.println("==== HelloWorldServiceImp ====");
  System.out.println(user.getUsername()+user.getPassword());
  User user2 = loginDao.checkUser(user);
  if(null == user2){
   System.out.println("没有该用户");
   return false;
  }else {
   String encodePassword = StringUtil.MD5Encode(user.getPassword());
   System.out.println(encodePassword);
   if(user2.getPassword().equals(encodePassword)){
    return true;
   }else {
    System.out.println("密码错误");
    return false;
   }
  }
 }

}

在src下添加domain包,并添加User实体类

package domain;

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;
 }
}

在src下添加dao包,新建LoginDao.java

package dao;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import domain.User;

public class LoginDao extends SqlMapClientDaoSupport {
 public User checkUser(User user) throws DataAccessException{
  System.out.println("====== LoginDao ======");
  System.out.println(user.getUsername()+user.getPassword());
  return (User)this.getSqlMapClientTemplate().queryForObject("TB_USER.selectUserByName",user);
 }
}

 

在dao包下添加map包,并新建TB_USER_SqlMap.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="TB_USER" >
 <typeAlias alias="User" type="domain.User" />
 
  <select id="selectUserByName" resultClass="User" parameterClass="User" >
    select USERNAME, PASSWORD from TB_USER_INFO where USERNAME = #username:VARCHAR#
  </select>
 
</sqlMap>

 

在tutorial包下面添加StringUtil.java 用于密码MD5加密

package tutorial;
import java.security.MessageDigest;

public class StringUtil {

 private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5",
   "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

 /**
  * 转换字节数组为16进制字串
  *
  * @param b
  *            字节数组
  * @return 16进制字串
  */

 public static String byteArrayToHexString(byte[] b) {
  StringBuffer resultSb = new StringBuffer();
  for (int i = 0; i < b.length; i++) {
   resultSb.append(byteToHexString(b[i]));
  }
  return resultSb.toString();
 }

 private static String byteToHexString(byte b) {
  int n = b;
  if (n < 0)
   n = 256 + n;
  int d1 = n / 16;
  int d2 = n % 16;
  return hexDigits[d1] + hexDigits[d2];
 }

 public static String MD5Encode(String origin) {
  String resultString = null;

  try {
   resultString = new String(origin);
   MessageDigest md = MessageDigest.getInstance("MD5");
   resultString = byteArrayToHexString(md.digest(resultString
     .getBytes()));
  } catch (Exception ex) {

  }
  return resultString;
 }

}


最后添加前台EXT页面

 

在WEBROOT下新建view文件夹,将ext包导入该文件夹下,添加ext的支持。

新建extpage文件夹,在该文件夹下建立login.html和login.js

login.html文件如下:

<html>
  <head>
    <title>login.html</title>
 <link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css" />
    <script type="text/javascript" src="../ext/adapter/ext/ext-base.js"></script>
 <script type="text/javascript" src="../ext/ext-all.js"></script>
 <script type="text/javascript" src="login.js"></script>
  </head>  
  <body>    
  </body>
</html>

login.js文件如下:

Ext.onReady(function(){
 var credentialPrintForm = new Ext.form.FormPanel({
     id: 'credentialPrintForm',
        border: false,

        autoHeight:true,
        autoWidth:true,
        layout: 'form',
        style: 'padding-left:2px;padding-top:2px;padding-right:2px',
        labelWidth: 85,
  labelAlign:'right',
  frame: true,
        items: [{
         xtype: 'fieldset',
            border:false,
            layout: 'form',
            autoHeight: true,
            autoWidth:true,
            items: [
            {
             xtype: 'textfield',
                fieldLabel:'用户名',
                width: 150,
                name:'user.username'
            },{
                xtype: 'textfield',
                inputType: 'password',
                fieldLabel:'密码',
                width: 150,
                name:'user.password'          
            }]          
           
        }]
       
 });
       
    var credentialPrint_oRevertWindow = new Ext.Window({
     id: '',
        title: '系统登录',
        width: 325,
        height: 162,
        modal: true,
        draggable:false,  //禁止拖动
  resizable: false,   //禁止改变大小
  constrainHeader: true,
  closable:false,
        items: [credentialPrintForm],
        buttons: [{
      text:'登录',
         tooltip:'登录',
         handler:function(){
          credentialPrintForm.getForm().submit({
     waitTitle:'消息',
     waitMsg :'请求提交中,请稍后...',
     url:'HelloWorld.action',
     method:'POST',
     success:function(fundBuy_form,action){
      var record = action.result.data;
      Ext.Msg.alert('消息',action.result.msg);
      document.location='../../HelloWorld.jsp';
     },
     failure : function(fundBuy_form, action) {
         if(action.failureType == Ext.form.Action.SERVER_INVALID){
       Ext.Msg.alert('错误',action.result.errors);
      }else if(action.failureType == Ext.form.Action.CONNECT_FAILURE){
       Ext.Msg.alert('错误','网络连接错误,请稍后再试!');
      }else{
       Ext.Msg.alert('错误','请求后台出错!');
      }
     }
    });      
         }
        }, {
         text: '重置',
         tooltip: '重置',
         handler: function(){
             credentialPrintForm.getForm().reset();
         }
        }]
    });       
    credentialPrint_oRevertWindow.show();
})

 

 

以上就是整个例子,在测试过程中,遇到一个"here is no Action mapped for action name HelloWorld"错误,查看网上有几种解决方案:

            1) 查看struts配置文档中配置的action名称,是否与表单提交中action相同
            2) 查看result是否正确,注意type=""中的值

            3)将struts.xml放到src下

仔细看过我的程序似乎都不存在这些问题,折腾了半天,原来是struts2-json-plugin-2.1.8.jar没有导入。晕死。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值