《Spring学习笔记》:Spring、Hibernate、struts2的整合(以例子来慢慢讲解,篇幅较长)

《Spring学习笔记》:Spring、Hibernate、struts2的整合(以例子来慢慢讲解,篇幅较长)

最近在看马士兵老师的关于Spring方面的视频,讲解的挺好的,到了Spring、Hibernate、struts2整合这里,由于是以例子的形式来对Spring+Hibernate+struts2这3大框架进行整合,因此,自己还跟着写代码的过程中,发现还是遇到了很多问题,因此,就记录下。

特此说明:本篇博文完全参考于马士兵老师的《Spring视频教程》

本篇博文均以如下这个例子一步一步的将Hibernate、struts、spring整合进来。

现在我们要实现这样一个功能:

有一个用户注册的页面,当用户进行在注册页面进行信息的填写之后,会出现如下的两种情况:

1、如果信息符合要求,则显示登录成功的页面并将用户信息写入到数据库中

2、如果信息不符合要求,则显示登录失败的页面。

本篇博文为Spring、Hibernate、struts2的整合经历的如下的阶段
1、两层架构的实现
2、两层架构+Entity+Service
3、三层架构:两层架构+Entity+Service+Hibernate(引入Hibernate)
4、N层+DAO层+抽象层
5、N层架构+Hibernate+struts(引入struts)
6、N层架构+Hibernate+struts+spring

下面就围绕上面的例子来慢慢将Spring、Hibernate和Struts进行整合进来。

1、两层架构的实现

我们首先采用两层架构来实现上面所描述的功能。

jsp+数据库的两层架构

具体设计如下:

实现代码

主要涉及到如下的4个jsp文件:

1、register.jsp

2、registerDeal.jsp

3、registerSuccess.jsp

4、registerFail.jsp

关于以上4个jsp文件的代码如下

1、register.jsp

这个文件主要就是一个表单form。具体内容如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">  
    <title>登陆界面</title>
  </head>

  <body>
    <form action="registerDeal.jsp" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name= "password"><br>
        确认密码:<input type="password" name="password2"><br>
        <input type="submit" value="提交">
    </form>
  </body>
</html>

2、registerDeal.jsp

这个文件包括主要的业务逻辑,主要用于接收register.jsp中用户输入的数据,以及和数据库打交道,进行数据的存储。下面的代码是我们比较熟悉的代码。

<%@page import="java.sql.Connection"%>
<%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
String username=request.getParameter("username");
String password=request.getParameter("password");
String password2=request.getParameter("password2");

Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost/spring", "root", "123456");

String sqlQuery="select count(*) from user where username=?";

PreparedStatement psQuery=conn.prepareStatement(sqlQuery);
psQuery.setString(1, username);
ResultSet rs=psQuery.executeQuery();
rs.next();
int count=rs.getInt(1);
//如果count>0  则跳转到registerFail.jsp页面  ,否则跳转到 registerSuccess.jsp页面并将用户的信息插入到数据库中
if(count>0){
    response.sendRedirect("registerFail.jsp");
    psQuery.close();
    conn.close();
    return;
}

String sqlInsert="insert into user values(null,?,?)";
PreparedStatement ps=conn.prepareStatement(sqlInsert);
ps.setString(1, username);
ps.setString(2,password);
ps.executeUpdate();
response.sendRedirect("registerSuccess.jsp");
psQuery.close();
ps.close();
conn.close();

%>

3、registerSuccess.jsp registerFail.jsp

这两个jsp文件比较简单,均只在页面中,显示Success / Fail信息。

例如:registerSuccess.jsp中body下的代码为:

<body>
        Success. <br>
</body>

要注意的几点是:

1、在MySQL数据库中建立名为spring的database和名为user的table

2、需要在项目中导入数据库驱动包。如下:

在浏览器中输入:http://localhost:8080/Spring_Register/register.jsp

会看到如下的登陆界面:

当我们在登陆界面数据信息后点击提交就会进行相应的跳转,以及将信息写入数据库中。

以上就通过jsp+数据库两层架构实现了这样一个简单的功能。

2、三层架构:两层架构+Entity+Service

上面所完成的所有功能均在jsp中实现,根本就没有体现面向对象编程的思维逻辑,因此,我们在上面的两层架构中引入Entity+Service来完成上面描述的功能。

2.1:定义一个User类

内容如下:

package com.register.model;

    public class User {
        private String username;
        private String password;
        //getter  setter方法

    }

2.2:定义一个UserManager类来管理User

内容如下:

import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;

    import com.register.model.User;

    public class UserManager {
    /*
     * 判断用户是否已在数据库中存在
     * */
    public boolean exists(User user) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn=DriverManager.getConnection("jdbc:mysql://localhost/spring", "root", "123456");

        String sqlQuery="select count(*) from user where username=?";
        PreparedStatement psQuery=conn.prepareStatement(sqlQuery);
        psQuery.setString(1, user.getUsername());
        ResultSet rs=psQuery.executeQuery();
        rs.next();
        int count=rs.getInt(1);
        if(count>0){
            psQuery.close();
            conn.close();
            return true;
        }
        return false;

    }
    /*
     * 函数功能:将用户的信息保存到数据库中
     * */
    public void save(User user) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn =DriverManager.getConnection("jdbc:mysql://localhost/spring",
                "root", "123456");

        String sql="insert into user values(null,?,?)";
        PreparedStatement ps=conn.prepareStatement(sql);
        ps.setString(1, user.getUsername());
        ps.setString(2, user.getPassword());
        ps.executeUpdate();
        ps.close();
        conn.close();


    }
}

此文件中的代码基本上就是对两层架构中registerDeal.jsp文件中的内容进行了一个提取和封装。

因此,在registerDeal.jsp文件中的内容如下

registerDeal.jsp中主要完成的是根据用户信息是否已经在数据库中存在完成页面的跳转。

<%@page import="java.sql.Connection"%>
    <%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="UTF-8"%>
    <%@ page import="com.register.model.*" %>
    <%@ page import="com.register.service.*" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    String password2=request.getParameter("password2");

    User user=new User();
    user.setUsername(username);
    user.setPassword(password);

    UserManager um=new UserManager();
    boolean exists=um.exists(user);
    if(exists){
        response.sendRedirect("registerFail.jsp");
        return;
    }

    um.save(user);
    response.sendRedirect("registerSuccess.jsp");

    %>

其它文件与两层架构中文件内容一致,这样就利用两层架构+Entity+Service,即三层架构来完成了此功能。这样的三层架构模型如下:

在两层架构中,jsp需要和数据库交互,在三层架构中,jsp就不再需要和数据库交互了。

这样我们离Spring/Hibernate/struts2整合又进了一步。

3、三层架构+Hibernate

在上面的三层架构中,我们是在UserManager中直接利用如下的语句完成数据库的交互

public void save(User user) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn =DriverManager.getConnection("jdbc:mysql://localhost/spring",
                "root", "123456");

        String sql="insert into user values(null,?,?)";
        PreparedStatement ps=conn.prepareStatement(sql);
        ps.setString(1, user.getUsername());
        ps.setString(2, user.getPassword());
        ps.executeUpdate();
        ps.close();
        conn.close();


    }

想上面这样的语句不是面向对象的,因此,这里我们就顺其自然的引入了Hibernate,利用Hibernate来和数据库进行交互。架构图如下

具体实现如下:

1、在工程WebRoot/WEB-INF/lib引入Hibernate的一些jar包

2、添加配置文件hibernate.cfg.xml

3、利用Annotation来注解实体类User。

4、其它文件中的代码与三层架构的代码一致,只需要更改UserManager类中的代码,代码如下:

import java.util.List;

    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;

    import com.register.model.User;

    public class UserManager {
    private SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
    /*
     * 判断用户是否已在数据库中存在
     * */

    public boolean exists(User user) throws Exception{
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //利用hql来查询数据库中是否已经存在此名字的用户
        String hql="from User as u where u.username=?";
        Query query=session.createQuery(hql);
        query.setString(0, user.getUsername());
        List list=query.list();
        if(!list.isEmpty()){
            return true;
        }
        session.getTransaction().commit();
        return false;

    }
    /*
     * 函数功能:将用户的信息保存到数据库中
     * */
    public void save(User user) throws Exception{
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();

    }
}

以上就是借用了Hibernate来完成和数据库的交互。

4、N层+DAO层+抽象层

上面是利用了Hibernate,在UserManager中调用Hibernate来完成数据库的交互。为了跨数据库平台等要求,需要引入DAO层,用DAO层来完成数据库的CRUD操作。

具体结构如下:

而关于DAO层,我们可能会有多种具体实现方式,对于Service层,我们也可能有多种具体的实现,因此,我们也就引入了面向接口编程。

引入DAO层和Service层结构以及他们之间的交互如下:

根据上面的结构图,我们只需要在第三节中介绍的:三层架构+Hibernate中的代码进行提取即可。

例如

1、UserDao接口中的代码如下:

public interface UserDao {
    public void save(User user);
    public boolean exists(User user);
}

2、UserDAO的实现UserDaoImpl类的代码如下:

public class UserDaoImpl implements UserDao{

    @Override
    public void save(User user) {
        SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();
    }

    @Override
    public boolean exists(User user) {
        SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
        Session session=sessionFactory.getCurrentSession();
        session.beginTransaction();
        //利用hql来查询数据库中是否已经存在此名字的用户
        String hql="from User as u where u.username=?";
        Query query=session.createQuery(hql);
        query.setString(0, user.getUsername());
        List list=query.list();
        if(!list.isEmpty()){
            return true;
        }
        session.getTransaction().commit();
        return false;
    }

}

3、UserManager接口的代码如下

public interface UserManager {
        public void save(User user);
        public boolean exists(User user);
}

4、UserManager的实现UserManagerImpl类的代码如下:

public class UserManagerImpl implements UserManager{

    private UserDao userDao=new UserDaoImpl();

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public boolean exists(User user) {

        return userDao.exists(user);
    }

    public void save(User user) {

         userDao.save(user);
    }
}

从以上的4个文件可以看出,就是将原来的三层架构+Hibernate的UserManager类中的代码进行了抽取,并添加了DAO层来完成和数据库的交互。

整个工程的代码可以在这里提取:https://github.com/wojiushimogui/Spring_register_dao_impl

到此为止,我们又距离Spring 、Hibernate 、struts2融合又近了一点。

下一步将引入struts2框架

5、在第4种情况下引入Struts框架

在第4种情况下引入Struts框架,需要引入的东西如下:

1、Struts2相关的jar包

2、web.xml文件(放入WEB-INF目录下)

3、配置文件struts.xml(放在/src目录下)

4、Action类

其中,

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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>Spring_Register_Hibernate_Struts</display-name>
      <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>
    </web-app>

Action类的内容如下:

属性username/password/password2用来接收登录界面闯进来的参数。

public class LoginAction  extends ActionSupport{

    private String username;
    private String password;
    private String password2;

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

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }
    //判断user在数据库中是否存在来返回不同的字符串
    @Override
    public String execute() throws Exception {
        UserManager um=new UserManagerImpl();
        User user=new User();
        user.setUsername(username);
        user.setPassword(password);
        boolean exists=um.exists(user);
        if(exists){
            System.out.println("registerFail");
            return "fail";
        }

        um.save(user);
        System.out.println("registerSuccess");
        return "success";
    }   
}

struts.xml文件中的内容如下:

<?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="default" namespace="/" extends="struts-default">

        <action name="registerAction"  class="com.register.action.LoginAction">
            <result name="success">/registerSuccess.jsp</result>
            <result name="fail">/registerFail.jsp</result>
        </action>
    </package>

    </struts> 

这样,就引入了Struts,将registerDeal的逻辑放入到了Action类中的execute方法中。并根据execute返回的字符串显示不同的view。

在完成struts整合的过程中,遇到了很多问题,有的比较好解决,有的也纠结了很长时间,例如:相同但不同版本的jar包问题(避免冲突,保留最新的jar包)

在删除重复的jar包的过程中,也遇到了一些问题,如下:

在MyEclipse中直接删除时,是删不掉的,不知道为什么,但是有的包又可以直接删除,因为这个问题,自己折腾了半天才OK。

到这里为止,我们就整合了Hibernate 、struts,下面我们就将Spring整合进来。

6、整合Spring、Hibernate、struts(引入Spring)

这节就开始引入Spring来对一些单例对象及事务进行管理。

主要细节可以参考这篇博文:http://blog.csdn.net/qq7342272/article/details/7928814

需要进行以下步骤:

1、引入Spring 相关的jar包

2、配置文件:beans.xml文件

3、用@Resource @Component来对一些类和对象进行注解,供Spring来进行管理

下面主要贴下beans.xml文件中的代码,这个beans.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"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    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
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config />
    <!-- 使用@Resource进行自动注入,需要增加如下的配置 -->
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> 
    <!-- 检测那些类可以作为组件 -->
    <context:component-scan base-package="com.register"/>

    <aop:config></aop:config>  

    <!-- 配置一个SessionFactory -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/spring"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <!-- 数据库连接池保持的最小和最大的连接数 -->
        <property name="minIdle" value="5"/>
        <property name="maxIdle" value="30"/>
        <!--  
            当数据库连接因为某种原因断掉之后,再重新从连接池中拿另外一个连接时实际上这个连接可能  
            已经无效,所以为了确保所拿到的连接全都有效需要在获取连接,返回连接以及连接空闲时进行  
            有效性验证 下面3个设置为ture时进行验证,默认为false  
         -->  
        <!-- 取得连接时是否进行有效性验证 -->  
        <property name="testOnBorrow" value="true" />  
        <!-- 返回连接时是否进行有效性验证 -->  
        <property name="testOnReturn" value="true" />  
        <!-- 连接空闲时是否进行有效性验证 -->  
        <property name="testWhileIdle" value="true" />  
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 注意:我用的是Annotation的方式配置的Hibernate,
            这里的property的name是annotatedClasses 
        <property name="annotatedClasses">
            <list>
                <value>com.register.model.User</value>
                <value>com.register.service.impl.UserManagerImpl</value>
            </list>
        </property>
        --> 
        <property name="packagesToScan">
            <list>
                <value>com.register.model</value>           
            </list>
        </property>
        <property name="hibernateProperties">
            <props>  
                <!-- 设置Hibernate方言 -->  
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
                <!-- 是否打印sql -->  
                <prop key="hibernate.show_sql">true</prop>  
                <!-- 格式化sql -->  
                <prop key="hibernate.format_sql">true</prop>  
                <!-- 是否自动更新表 -->  
                <!-- 

                <prop key="hibernate.hbm2ddl.auto">update</prop>  
                <prop key="hibernate.current_session_context_class">thread</prop>  
                     最大抓取深度,如果为0,则关闭默认的外连接抓取。建议值为0-3  
                <prop key="hibernate.max_fetch_depth">1</prop>  
                     用于生成有助于调试的注释信息,默认为关闭 
                <prop key="hibernate.use_sql_comments">true</prop>  
                 -->
            </props>  
        </property>
    </bean>

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" >  
        <property name="dataSource" ref="dataSource" />
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  

    <aop:config>  
        <aop:pointcut id="txMethod" expression="execution(* com.register.dao..*.*(..))" />  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txMethod"/>  
    </aop:config>  
    <!-- AOP切面声明事务管理  --> 
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="save*" propagation="REQUIRED" /> <!-- 支持当前事务,如果执行到save开头的任何方法时没有事务则开启一个事务 这是最常见的方式-->  
            <tx:method name="update*" propagation="REQUIRED" /><!-- 支持当前事务,如果执行到update开头的任何方法时没有事务则开启一个事务 这是最常见的方式-->  
            <tx:method name="add*" propagation="REQUIRED" /><!-- 支持当前事务,如果执行到add开头的任何方法时没有事务则开启一个事务 这是最常见的方式-->  
            <tx:method name="delete*" propagation="REQUIRED" /><!-- 支持当前事务,如果执行到delete开头的任何方法时没有事务则开启一个事务 这是最常见的方式-->  
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> <!-- 支持当前事务,如果当前没有事务,就以非事务方式执行。只读 -->  
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/><!-- 支持当前事务,如果当前没有事务,就以非事务方式执行。只读 -->  
            <tx:method name="*" />  
        </tx:attributes>  
    </tx:advice>  


    <!-- <bean name="userManager" class="com.register.service.impl.UserManagerImpl" />  -->

</beans>

UserDaoImpl类的代码更改为如下:

@Component("userDao")
public class UserDaoImpl implements UserDao{

    private HibernateTemplate  hibernateTemplate;

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    @Resource
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public void save(User user) {
        this.hibernateTemplate.save(user);
    }

    @Override
    public boolean exists(User user) {
        List res=hibernateTemplate.find("from User as u where u.username=?", user.getUsername());
        if(res!=null&&res.size()>0){
            return true;
        }
        return false;   
    }
}

测试代码如下:

public class UserManagerTest {

    @Test
    public void testExists() {
        ApplicationContext context= new ClassPathXmlApplicationContext("/beans.xml");  
        UserManager um =(UserManager) context.getBean("userManager");       
//      UserManager um=new UserManagerImpl();
        User user=new User();
        user.setUsername("haowu");
        boolean exists=um.exists(user);
        assertEquals(false, exists);
    }

    @Test
    public void testSave() {
        ApplicationContext context= new ClassPathXmlApplicationContext("/beans.xml");  
        UserManager um =(UserManager) context.getBean("userManager");  
//      UserManager um=new UserManagerImpl();
        User user=new User();
        user.setUsername("haowuwu3");
        user.setPassword("123");
        boolean exists=um.exists(user);
        if(!exists){
            um.save(user);
            //如果我们不想从数据库中查看是否保存成功,则可以利用以下的代码来完成
            exists=um.exists(user);
            assertEquals(true, exists);
        }
        else{
            fail("save fail!!!");
        }
    }

}

将对象交给Spring来进行管理,在代码中我们比较常见的类似于UserDao userDao=new UserDaoImpl()这样的代码就不见了。

完整代码可以在这里提取:https://github.com/wojiushimogui/Spring_Register_Hibernate_Struts_0000_Final

7、registering Actions with Spring

registering Actions with Spring,即将Action也交给Spring来管理。

在Spring plugin文档中有如下一句话:

registering Actions with Spring is not required. The Spring alternative is there if you need it, but the framework will automatically create Actions objects from the action mappings. But, if you want to use Spring to inject your Actions, the option is there.

关于步骤,在Spring文档中说的比较清楚。有如下的几个步骤

1、Configure the Spring listener

在web.xml文件中加入:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2、Register your objects via the Spring configuration

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans default-autowire="autodetect">
        <bean id="personManager" class="com.acme.PersonManager" scope="prototype"/>
    ...
    </beans>

在本项目中,我们采用Annotation来注册Action

@Component("registerAction")  //此名字要与struts.xml文件中的action的名字一致
@Scope("prototype")  //一定要设置Scope为prototype
public class LoginAction  extends ActionSupport{
    private String username;
    private String password;
    private String password2;

    private UserManager userManager;

    public UserManager getUserManager() {
        return userManager;
    }
    @Resource
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }

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

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }
    //判断user在数据库中是否存在来返回不同的字符串
    @Override
    public String execute() throws Exception {
        User user=new User();
        user.setUsername(username);
        user.setPassword(password);
        

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

京东/优酷IOS面试题 - 2016-05-27 14:05:16

京东面试题 1、请写出以下代码输出 1 2 3 4 5   int a [ 5 ] = { 1 , 2 , 3 , 4 , 5 } ; int *ptr = ( int * ) ( a + 1 ) ; printf ( "%d, %d" , * ( a + 1 ) , * ( ptr + 1 ) ) ;   参考答案: 2, 随机值 这种类型题好像挺常见的。考的就是C语言上的指针的理解和数

Scroller源码详解 - 2016-05-27 14:05:15

View弹性滑动详解 之前写了一个滚动选择控件 WheelView ,在这个控件中我设计了弹性滚动的实现机制,再了解View弹性滚动之前,我们先来学习一下View滚动机制的实现. View的scrollTo/scrollBy 这里基于Android5.0版本的源码介绍View类中这两个函数的具体实现. scrollTo源码如下: /** * 对View设置滚动的x和y轴坐标. * @param x x轴滚动的终点坐标 * @param y y轴滚动的终点坐标 */ public void scrollTo

iOS之UIView动画 - 2016-05-27 14:05:15

概述 在AppStore中的应用越来越重视动画效果的使用,一个良好动画效果可以让两个状态之间平滑地过度,也可以利用动画吸引住用户的眼球,在UIView类中共有三个类目(Category)用于实现动画功能,分为UIViewAnimation、UIViewAnimationWithBlocks以及UIViewKeyframeAnimations,他们是Apple对核心动画(Core Animation)的封装,可以让我们不进行任何绘画等复杂操作的前提下实现大部分动画需求 UIView动画的用处 UIView类

Android自助餐之EventBus框架 - 2016-05-27 14:05:21

Android自助餐之EventBus框架 Android自助餐之EventBus框架 下载完整源代码 配置buildgrandle 实例化EventBus 注册事件监听 定义被传递的事件类 发送事件 处理时间 下载 完整源代码 配置build.grandle compile 'de.greenrobot:eventbus:2.4.0' 实例化EventBus eventBus=EventBus.builder().build(); 注册事件监听 eventBus.register(this); this

IOS高级笔试题 - 2016-05-27 14:05:21

2.Socket在传输过程中用的是什么类型的数据:结构体还是文本?如果是文本,那么怎么进行编码和解码? 参考答案: iOS Socket编程-Objective-C原生API版 iOS Socket编程-Objective-C基于CocoaAsyncSocket版 iOS Socket编程-Swift原生API版 iOS Socket编程-Swift基于AsyncSocket版 3、图片压缩处理问题 参考答案: 关于图片的压缩处理,在ios中常用的方法是先处理像素再处理尺寸。 4、在做图片优化处理的时候,
实现滑动的基本思想是:当触摸View时,系统记下当前触摸点坐标;当手指移动时,系统记下移动后的触摸点坐标,从而获取到相对于前一次坐标点的偏移量,并通过偏移量来修改View的坐标,这样不断重复,从而实现滑动过程. 2.1 Layout方法 在View进行绘制时,会调用onLayout()方法来设置显示的位置 通过修改View的left,top,right,bottom四个属性来控制View的坐标,在每次回调onTouchEvent的时候,获取一下触摸点的坐标: // 视图坐标方式 @Override pub

Linux驱动之输入子系统框架 - 2016-05-27 14:05:20

    好记性不如烂笔头,整理一下笔记~ Linux驱动之输入子系统框架 输入子系统将该类驱动划分为3部分     1、核心层 input.c     2、设备层 Gpio_keys.c ...     3、事件处理层 Evdev.c     事件处理层为纯软件的东西,设备层涉及底层硬件,它们通过核心层建立联系,对外提供open write等接口。 1、我们首先来看,核心层 input.c如何向外界提供接口     在 input_init 中注册了字符设备驱动     register_chrdev(I
主要讲解Android Studio中生成aar文件以及本地方式使用aar文件的方法。 在Android Studio中对一个自己库进行生成操作时将会同时生成*.jar与*.aar文件。 分别存储位置: *.jar:库 /build/intermediates/bundles/debug(release)/classes.jar *.aar:库 /build/outputs/aar/libraryname.aar 两者区别: *.jar: 只包含了class文件与清单文件 ,不包含资源文件,如图片等所有r
本文参考: http://www.cnblogs.com/kenshincui/p/3972100.html#autoid-3-0-0 总结的: 效果: 转场动画 就是从一个场景以动画的形式过渡到另一个场景。转场动画的使用一般分为以下几个步骤:    1.创建转场动画 CATransition    2.设置转场类型transtion.type、子类型transtion.subtype(可选)及其他属性    3.设置转场后的新视图并添加动画到图层    下表列出了常用的转场类型(注意私有API是苹果官方
一、 要实现高德地图定位呢,首先需要做好以下几步准备: 1. 在高德开放平台注册帐号 注册地址: http://lbs.amap.com 2. 在 开发 中下载Android平台下的 地图SDK和定位SDK文件 进入 相关下载 下载自己想要的功能或文件,图只是截取了 地图SDK 的页面, 定位SDK 也是一样,按自己想要的文件下载。下载完成后解压得到: - 3D地图包解压后得到:3D地图显示包“AMap_3DMap_VX.X.X_时间.jar”和库文件夹(包含armeabi、arm64-v8a等库文件)。