• 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/ 

  • 相关阅读:
    linux中添加ftp用户,并设置相应的权限
    mysql 命令管理
    阿里云服务器资料
    sql替换指定字段指定字符串
    apache本地域名ip重定向vhosts
    php数组序列化serialize与unserialize
    Android 开发第三天
    Android 开发第二天
    Android开发的第一天
    字符的截取方法使用的是Substring 和三目运算符
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5068245.html
Copyright © 2020-2023  润新知