zoukankan      html  css  js  c++  java
  • SSH框架

    Java EE中的SSH框架

     

        首先说明一下,本人目前主要从事.NET领域的工作,但对于C++、Java、OC等语言也略知一二,周末闲来无事,特花费一天的时间学习了一下Java中的SSH框架,希望把学习过程中的心得体会与园友们进行分享,共勉之。

        SSH框架主要是指Struts、Spring、Hibernate,其中Struts主要擅长Java EE开发中的MVC模式,其优点主要体现的视图和控制器的解耦上,Spring主要擅长于IOC(依赖注入)和AOP(面向切面的编程),主要是为了解决企业应用程序维护的复杂性问题成创立的,Hibernate是一个非常出色的ORM框架,拥有强大的一级二级缓存机制结合数据库连接池(POOL),大大提高CURD的操作效果,项目加入了Hibernate以后,还可以更好地进行面向对象的编程。

        一、Struts

        首先介绍Struts,在Web项目中加入Struts的jar包,并在Web.xml中添加 Struts的配置:

    复制代码
    <filter>
          <filter-name>struts2</filter-name>
          <filter-class>
              org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
          </filter-class>
      </filter>
      <filter-mapping>
          <filter-name>struts2</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    复制代码

        其中filter是指对用户请求的拦截,url-pattern中的/*是指使用Struts对所有的请求进行拦截。接着创建一个Login.jsp,源码如下:

    复制代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ page isELIgnored="false" %>
    <%@ taglib uri="/struts-tags" prefix="s"%>  
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>用户登录</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      
      <body>
          <s:form action="Login.action" method="post">
            <s:textfield name="UserName" label="帐号">
              </s:textfield>
      
              <s:password name="Password" label ="密码">
              </s:password>
              <s:submit value="登录"></s:submit>
          </s:form>
     </body>
    </html>
    复制代码

        其中的【s:】的的标签是由Struts的标签库提供的,Struts中提供了一个非常强大的标签库,利用这些标签库可以辅助开发者进行HTML的表单设计和一些业务逻辑控制,form标签中的action指向的是我们的控制器,默认是以.action结尾,我们添加一个控制器类,用于处理用户的登录请求,命名为Login.java,源码如下:

    复制代码
    package account;
    
    import com.opensymphony.xwork2.Action;
    import com.opensymphony.xwork2.ActionSupport;
    
    public class Login extends ActionSupport {
        public String UserName;
        public String Password;
        public String getUserName() {
            return UserName;
        }
        public void setUserName(String userName) {
            UserName = userName;
        }
        public String getPassword() {
            return Password;
        }
        public void setPassword(String password) {
            Password = password;
        }
        
        //对表单进行验证
        @Override
        public void validate() {
            if(UserName.equals(""))
            {
                this.addFieldError("UserName", "用户名不允许为空!");
            }
            if(Password.equals("")){
                this.addFieldError("Password", "密码不能为空!");
            }
        };
        //执行控制器逻辑
        public String execute()
        {
            if(UserName.equals("admin") && Password.equals("123")){
                return Action.SUCCESS;
            }
            else {
                return Action.ERROR;
            }
        }
    }
    复制代码

        其中Login的类继承自ActionSupport,ActionSupport类实现了Struts的Action的接口,并且还具有了对表单进行验证的功能,在Login中重写alidate就可以对表单进行验证,在出错的时候,添加错误信息。execute相当于控制器的“main”函数,其必须为public类型,并且返回值为String,在本例中返回的结果为Action中的5个字符常量之一(当然,也可以自定义返回接口)。

        接下来在src的目录下对struts.xml添加相应的配置,把控制器和我们的jsp文件关联起来,配置的代码如下:

    复制代码
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
    <package name="ghyStruts" extends="struts-default">
    <action name="Login" class="account.Login">
        <result name="success" type="redirectAction">
        <param name="username">${UserName}</param>
        <param name="actionName">index</param>
        </result>
        <result name="error">/error.jsp</result>
        <result name="input">Login.jsp</result>
    </action>
    
    <action name="index" class="home.index">
        <result name="index">/index.jsp</result>
    </action>
    </package>
    </struts>    
    复制代码

        其中的action代表了一个控制器请求,result是指请求返回的结果(控制器类中的execute方法的返回值),其中的name与返回的字符串必须要对应起来,type="redirectAction"代表跳转到另外一个action中,还可以在跳转的时候,添加参数,参数的名称、值和跳转结果的action的名字都是由param指定。如果需要直接返回到另外一个jsp页面,可以直接在result中添加jsp的名字,如/error.jsp,其中的“/”代表根目录。

         Struts中提供了大量的标签库,标签库中的所有的标签头都是以s开头,格式为s:xxx,以其中的控制标签if为例:

    <s:if test="UserName=='admin'">您好,管理员!</s:if>
    <s:else>您好,普通用户!</s:else>

        其中test是判断条件,UserName为控制器返回的属性,里面的内容是条件为真时的结果。

        二、Spring

        下面来介绍一些Spring框架实现的IoC,首先添加一个接口IService,代码如下:

    package lizon;
    
    public interface IService {
        public void save();
    }

        再添加一个Service类实现该接口:

    复制代码
    package service;
    
    import lizon.IService;
    
    public class Service implements IService {
        public void save() {
            System.out.println("保存");
        }
    }
    复制代码

        添加一个Run,来调用接口的save:

    复制代码
    package lizon;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import service.Service;
    
    public class Run {
        private IService isvc;
        public IService getIsvc() {
            return isvc;
        }
        public void setIsvc(IService isvc) {
            this.isvc = isvc;
        }
        public static void main(String[] args) {
            
        }
    }
    复制代码

        注意,我们的Run类中有一个IService接口的属性,接下来,我们通过Spring的配置,把Service注入到IService中:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
        <bean id="svc" class="service.Service">
        </bean>
        
        <bean id="run" class="lizon.Run">
            <property name="isvc" ref="svc"></property>
        </bean>
    </beans>
    复制代码

        首先配置一个Service的bean,并给它的实例起个名字叫svc,然后配置一个run的bean,并把svc的实现,注入到Run类中的IService接口中。这样在Run的main方法中,我们就可以这样调用:

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Run run = (Run) context.getBean("run");
    run.isvc.save();

        通过ApplicationContext来获得配置文件中的接口的实现,然后进行调用。在我们的Run方法中没有涉及到任何实现的代码,有效地对接口和实现进行了解耦。Spring框架可以注入多种数据类型,包括基本数据类型、null类型、List、Map、Set等,还可以对构造函数进行注入。并且在配置文件中改变scope的属性,可以轻松地实现单例模式(Singleton)或多实例模式(Prototype)。

        Spring中还有另一个擅长的领域:AOP,下面来介绍一下在Spring中AOP的实现方法,借用上面例子中的接口和实现,代码如下:

    package lizon;
    
    public interface IService {
        public void save();
    }
    复制代码
    package service;
    
    import lizon.IService;
    
    public class Service implements IService {
        public void save() {
            System.out.println("保存");
        }
    }
    复制代码

        假如这个接口和实现是我们系统中多年前完成的功能模块,现在我们想在save方法中加入执行前后的日志,但是根据软件设计中对修改关闭、对扩展开放的原则,我们不应该直接修改save方法,而是使用AOP对save方法进行扩展,下面定义一个基于Spring的对方法进行增强的类:

    复制代码
    package Interceptor;
    
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    
    public class mylog implements MethodInterceptor{
    
        @Override
        public Object invoke(MethodInvocation arg0) throws Throwable {
            System.out.println("方法执行前");
            arg0.proceed();
            System.out.println("方法执行后");
            return null;
        }
    
    }
    复制代码

        我们定义的这个mylog的类继承自Spring中的MethodInterceptor,并重写了该类中的invoke方法,其中arg0.proceed()是执行被代理的方法,并在执行的前后加入了自定义的日志,最后我们配置一个Spring,让这个增强的方法和原方法关联起来:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
        <bean id="svc" class="service.Service">
        </bean>
        
        <bean id="mylog" class="Interceptor.mylog"></bean>
        
        <bean id="myproxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces">
                <value>lizon.IService</value>
            </property>
            
            <property name="target" ref="svc"></property>
            
            <property name="interceptorNames">
                <list>
                <value>mylog</value>
                </list>
            </property>
        </bean>
    
    </beans>
    复制代码

        在这个配置文件中,首先定义了接口的实现svc和代理类mylog,然后配置代理的接口,proxyInterfaces里面的value是我们需要增强的接口,target中的ref是接口的实现,interceptorNames中配置我们使用哪一个代理类。调用方法如下:

    public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            IService isvc = (IService) context.getBean("myproxy");
            isvc.save();
        }

        三、Hibernate

        最后介绍一下Hibernate,首先用数据库脚本创建一个User表:

    复制代码
    CREATE TABLE USER
    (
        USERID INTEGER NOT NULL PRIMARY KEY, 
        USERNAME VARCHAR(12) NOT NULL, 
        PASSWORD VARCHAR(50) 
    );
    复制代码

        接着创建一个User类:

    复制代码
    package lizon;
    
    public class User {
        private int userid;
        private String username;
        private String password;
        public int getUserid() {
            return userid;
        }
        public void setUserid(int userid) {
            this.userid = userid;
        }
        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;
        }
        
        
    }
    复制代码

        再创建一个User.hbm.xml把User类和USER表关联起来:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            '-//Hibernate/Hibernate Mapping DTD 3.0//EN'
            'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
    <hibernate-mapping>
        <class name="lizon.User" table="USER">
            <id name="userid" column="USERID">
                <generator class="increment"/>
            </id>
            <property name="username" column="USERNAME"></property>
            <property name="password" column="PASSWORD"></property>
        </class>
    </hibernate-mapping>
    复制代码

        添加一段代码看一下Hibernate是怎么跟数据交互的:

    复制代码
    package lizon;
    
    import hb4.HibernateSessionFactory;
    
    import org.hibernate.Session;
    
    public class Run {
        public static void main(String[] args) {
    
            Session session = null;  
            try{  
                //取得Session
                session = HibernateSessionFactory.getSession();  
                //开启事务处理 
                session.beginTransaction();  
                //新增一个User,这时候对象是瞬时状态
                User user = new User();
                user.setUsername("lizon");  
                user.setPassword("123");  
    
                //保存User对象 ,这时候对象是持久化状态 
                session.save(user);  
                //提交事务  
                session.getTransaction().commit();  
            }catch(Exception e){  
                e.printStackTrace();  
                //回滚事务  
                session.getTransaction().rollback();  
            }finally{  
                if(session != null){  
                    if(session.isOpen()){  
                        //关闭session,这时候的对象是游离状态
                        session.close();  
                    }  
                }  
            }  
        }
    }
    复制代码

        在这段代码中,我们首先实例化了一个新的User对象,然后使用Hibernate的Session把对象保存到了数据库,甚至还包含了一个事务处理,在这中间,我们没有使用任何的sql语句,仅仅对User对象进行操作就可以持久化到数据,使用Hibernate减少了大量的重复JDBC的代码,可以更好地实现面向对象的编程,当然,这里介绍的只是Hibernate的冰山一角,由于篇幅有限,对于Hibernate的外键关联、延迟加载、HQL等有兴趣的话可以自行学习。

        由于对SSH框架接触时间不长(仅一天时间,囧),难免有不周的地方,还望各位且看且珍惜。

    作者:Lizon 
    出处:http://www.cnblogs.com/lizongshen/ 

  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5068245.html
Copyright © 2011-2022 走看看