zoukankan      html  css  js  c++  java
  • myeclipse2013下整合struts2、spring3、jpa2

          在myeclipse下,利用myeclipse自带的功能,为项目添加struts、jpa、spring的功能,可以极大的缩短开发时间。

         本文是利用struts为表现层,jpa为持久层,spring为业务层,利用spring的依赖注入管理struts的action和jpa的entityManager、jpa的事务管理。

         记录学习的脚步,!!!!!

    1.在myeclipse下新建web project,名为SSJTest,并添加oracle 11g的驱动jar包,如下


    2.为SSJTest项目添加spring功能,如下


    点击install spring facet后,下一步如下


    修改运行的目标环境后,其他的默认即可,一直点next,直至完成.

    完成后 效果如下


    打开web.xml文件中会发现 添加了如下配置信息

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
      </context-param>

    上面的ContextLoaderListener监听器用于初始化spring容器,此监听器会查找contextConfigLocation参数,然后获取其值作为spring容器的配置文件,如果不指定contextConfigLocation参数的话,则默认会查找/WEB-INF/applicationContext.xml 下面的配置文件

     3.给 SSJTest添加jpa功能,与添加sping功能很类似,并且利用myeclipse自带的jpa工程翻转,将oracle下面的stus表进行实体映射,并生成其数据访问层和数据访问层接口,

    部分截图如下

    jpa翻转


    配置dao,并交由spring来进行管理


    其他步骤,均下一步即可.最终效果


      此时为了spring为jpa管理其事务,还需在StusDao上加入@Transactional注解,以便于spring容器进行事务管理


          在添加struts功能之前,测试下spring与jpa的整合是否成功,于是添加junit test

      测试代码:

    package com.undergrowth;
    
    import static org.junit.Assert.*;
    
    import java.sql.Timestamp;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    import java.util.UUID;
    
    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class StusDAOTest {
    
    	private static ApplicationContext ac;
    	private static IStusDAO  isd;
    	
    	@BeforeClass
    	public static void setUpBeforeClass() throws Exception {
    		//初始化spring容器
    		ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    		//获取stus的dao
    		isd=(IStusDAO) ac.getBean("StusDAO");
    		
    	}
    
    	@Test
    	public void testSave() {
    		Stus stus=new Stus(UUID.randomUUID().toString(), "马化腾", 45.0, Timestamp.valueOf(new Date().toLocaleString()));
    		isd.save(stus);
    	}
    
    	@Test
    	public void testDelete() {
    		fail("Not yet implemented");
    	}
    
    	@Test
    	public void testUpdate() {
    		fail("Not yet implemented");
    	}
    
    	@Test
    	public void testFindAll() {
    		List<Stus> listStus=isd.findAll();
    		for (Stus stus : listStus) {
    			System.out.println(stus);
    		}
    	}
    
    }
    

    先运行testSave然后运行testFindAll,控制台输出

    log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    [EL Info]: 2014-02-16 15:24:51.512--ServerSession(31211440)--EclipseLink, version: Eclipse Persistence Services - 2.4.2.v20130514-5956486
    [EL Info]: connection: 2014-02-16 15:24:52.123--ServerSession(31211440)--file:/D:/learnsoftware/java/AndroidDevelop/myeclipse_2014_1_23/SSJTest/build/classes/_SSJTest login successful
    Stus [stuId=b31494c8-1806-49b5-b490-49e8a57e38e3, stuName=马化腾, stuAge=45.0, stuBirthday=2014-02-16 15:24:34.0]
    

    表明spring与jpa合成没有问题


    4.为其添加struts功能,添加struts功能之后,在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>
    
        <!-- 打开调试模式,获取更多的调试信息 -->
       <constant name="struts.devMode" value="true"></constant>
      <!--  使用spring容器来管理struts的action -->
    	<constant name="struts.objectFactory" value="spring"></constant>
    	
    	
    	<package name="stus" namespace="/stus" extends="struts-default">
    	<!-- 使用*占位符来扩展多个方法 -->
    		<action name="stus_*" class="stusAction" method="{1}">
    			<result name="list">/WEB-INF/page/stusList.jsp</result>
    		</action>
    	</package>
    </struts>    
    

    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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
    	xmlns:tx="http://www.springframework.org/schema/tx">
    
        
    	<bean id="entityManagerFactory"
    		class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    		<property name="persistenceUnitName" value="SSJTest" />
    	</bean>
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory" />
    	</bean>
    	<!-- 用于jpa的事务管理 -->
    	<tx:annotation-driven transaction-manager="transactionManager" />
    	<bean
    		class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">
    	</bean>
    	<bean
    		class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
    	</bean>
    	<bean id="StusDAO" class="com.undergrowth.StusDAO"></bean>
    	
    	<bean id="stusAction" class="com.undergrowth.action.StusAction">
    	<!-- 注入数据访问层 -->
    		<property name="stusDAO" ref="StusDAO"></property>
    	</bean>
    </beans>

    中转的action为

    package com.undergrowth.action;
    
    import java.util.List;
    
    import com.undergrowth.IStusDAO;
    import com.undergrowth.Stus;
    
    public class StusAction {
    	
    	private List<Stus> listPerson;
    	private IStusDAO stusDAO;
    	
    	public IStusDAO getStusDAO() {
    		return stusDAO;
    	}
    
    	public void setStusDAO(IStusDAO stusDAO) {
    		this.stusDAO = stusDAO;
    	}
    
    	public List<Stus> getListPerson() {
    		return listPerson;
    	}
    
    	public void setListPerson(List<Stus> listPerson) {
    		this.listPerson = listPerson;
    	}
    	
    	
    	public String getList()
    	{
    		this.listPerson=stusDAO.findAll();
    		return "list";
    	}
    	
    }
    

    页面前段显示的界面,如下

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags" prefix="s" %>    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>信息列表</title>
    </head>
    <body>
    	<s:iterator value="listPerson">
    		<s:property/>
    	</s:iterator>
    </body>
    </html>


    持久层的Stus.java

    package com.undergrowth;
    
    import java.sql.Timestamp;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    /**
     * Stus entity. @author MyEclipse Persistence Tools
     */
    @Entity
    @Table(name = "STUS", schema = "UNDER")
    public class Stus implements java.io.Serializable {
    
    	// Fields
    
    	private String stuId;
    	private String stuName;
    	private Double stuAge;
    	private Timestamp stuBirthday;
    
    	// Constructors
    
    	/** default constructor */
    	public Stus() {
    	}
    
    	/** full constructor */
    	public Stus(String stuId, String stuName, Double stuAge,
    			Timestamp stuBirthday) {
    		this.stuId = stuId;
    		this.stuName = stuName;
    		this.stuAge = stuAge;
    		this.stuBirthday = stuBirthday;
    	}
    
    	// Property accessors
    	@Id
    	@Column(name = "STU_ID", unique = true, nullable = false, length = 50)
    	public String getStuId() {
    		return this.stuId;
    	}
    
    	public void setStuId(String stuId) {
    		this.stuId = stuId;
    	}
    
    	@Column(name = "STU_NAME", nullable = false, length = 30)
    	public String getStuName() {
    		return this.stuName;
    	}
    
    	public void setStuName(String stuName) {
    		this.stuName = stuName;
    	}
    
    	@Column(name = "STU_AGE", nullable = false, precision = 0)
    	public Double getStuAge() {
    		return this.stuAge;
    	}
    
    	public void setStuAge(Double stuAge) {
    		this.stuAge = stuAge;
    	}
    
    	@Column(name = "STU_BIRTHDAY", nullable = false, length = 7)
    	public Timestamp getStuBirthday() {
    		return this.stuBirthday;
    	}
    
    	public void setStuBirthday(Timestamp stuBirthday) {
    		this.stuBirthday = stuBirthday;
    	}
    
    	@Override
    	public String toString() {
    		return "Stus [stuId=" + stuId + ", stuName=" + stuName + ", stuAge="
    				+ stuAge + ", stuBirthday=" + stuBirthday + "]";
    	}
    
    	
    	
    }

    数据访问层StusDao.java

    package com.undergrowth;
    
    import java.sql.Timestamp;
    import java.util.List;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Repository;
    import org.springframework.transaction.annotation.Transactional;
    
    /**
     * A data access object (DAO) providing persistence and search support for Stus
     * entities. Transaction control of the save(), update() and delete() operations
     * can directly support Spring container-managed transactions or they can be
     * augmented to handle user-managed Spring transactions. Each of these methods
     * provides additional information for how to configure it for the desired type
     * of transaction control.
     * 
     * @see com.undergrowth.Stus
     * @author MyEclipse Persistence Tools
     */
    @Transactional
    @Repository
    public class StusDAO implements IStusDAO {
    	private static final Log logger = LogFactory.getLog(StusDAO.class);
    	// property constants
    	public static final String STU_NAME = "stuName";
    	public static final String STU_AGE = "stuAge";
    
    	private EntityManager entityManager;
    
    	@PersistenceContext
    	public void setEntityManager(EntityManager entityManager) {
    		this.entityManager = entityManager;
    	}
    
    	private EntityManager getEntityManager() {
    		return entityManager;
    	}
    
    	/**
    	 * Perform an initial save of a previously unsaved Stus entity. All
    	 * subsequent persist actions of this entity should use the #update()
    	 * method. This operation must be performed within the a database
    	 * transaction context for the entity's data to be permanently saved to the
    	 * persistence store, i.e., database. This method uses the
    	 * {@link javax.persistence.EntityManager#persist(Object)
    	 * EntityManager#persist} operation.
    	 * <p>
    	 * User-managed Spring transaction example:
    	 * 
    	 * <pre>
    	 * TransactionStatus txn = txManager
    	 * 		.getTransaction(new DefaultTransactionDefinition());
    	 * StusDAO.save(entity);
    	 * txManager.commit(txn);
    	 * </pre>
    	 * 
    	 * @see <a href =
    	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
    	 *      container-managed transaction examples</a>
    	 * @param entity
    	 *            Stus entity to persist
    	 * @throws RuntimeException
    	 *             when the operation fails
    	 */
    	public void save(Stus entity) {
    		logger.info("saving Stus instance");
    		try {
    			getEntityManager().persist(entity);
    			logger.info("save successful");
    		} catch (RuntimeException re) {
    			logger.error("save failed", re);
    			throw re;
    		}
    	}
    
    	/**
    	 * Delete a persistent Stus entity. This operation must be performed within
    	 * the a database transaction context for the entity's data to be
    	 * permanently deleted from the persistence store, i.e., database. This
    	 * method uses the {@link javax.persistence.EntityManager#remove(Object)
    	 * EntityManager#delete} operation.
    	 * <p>
    	 * User-managed Spring transaction example:
    	 * 
    	 * <pre>
    	 * TransactionStatus txn = txManager
    	 * 		.getTransaction(new DefaultTransactionDefinition());
    	 * StusDAO.delete(entity);
    	 * txManager.commit(txn);
    	 * entity = null;
    	 * </pre>
    	 * 
    	 * @see <a href =
    	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
    	 *      container-managed transaction examples</a>
    	 * @param entity
    	 *            Stus entity to delete
    	 * @throws RuntimeException
    	 *             when the operation fails
    	 */
    	public void delete(Stus entity) {
    		logger.info("deleting Stus instance");
    		try {
    			entity = getEntityManager().getReference(Stus.class,
    					entity.getStuId());
    			getEntityManager().remove(entity);
    			logger.info("delete successful");
    		} catch (RuntimeException re) {
    			logger.error("delete failed", re);
    			throw re;
    		}
    	}
    
    	/**
    	 * Persist a previously saved Stus entity and return it or a copy of it to
    	 * the sender. A copy of the Stus entity parameter is returned when the JPA
    	 * persistence mechanism has not previously been tracking the updated
    	 * entity. This operation must be performed within the a database
    	 * transaction context for the entity's data to be permanently saved to the
    	 * persistence store, i.e., database. This method uses the
    	 * {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
    	 * operation.
    	 * <p>
    	 * User-managed Spring transaction example:
    	 * 
    	 * <pre>
    	 * TransactionStatus txn = txManager
    	 * 		.getTransaction(new DefaultTransactionDefinition());
    	 * entity = StusDAO.update(entity);
    	 * txManager.commit(txn);
    	 * </pre>
    	 * 
    	 * @see <a href =
    	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
    	 *      container-managed transaction examples</a>
    	 * @param entity
    	 *            Stus entity to update
    	 * @return Stus the persisted Stus entity instance, may not be the same
    	 * @throws RuntimeException
    	 *             if the operation fails
    	 */
    	public Stus update(Stus entity) {
    		logger.info("updating Stus instance");
    		try {
    			Stus result = getEntityManager().merge(entity);
    			logger.info("update successful");
    			return result;
    		} catch (RuntimeException re) {
    			logger.error("update failed", re);
    			throw re;
    		}
    	}
    
    	public Stus findById(String id) {
    		logger.info("finding Stus instance with id: " + id);
    		try {
    			Stus instance = getEntityManager().find(Stus.class, id);
    			return instance;
    		} catch (RuntimeException re) {
    			logger.error("find failed", re);
    			throw re;
    		}
    	}
    
    	/**
    	 * Find all Stus entities with a specific property value.
    	 * 
    	 * @param propertyName
    	 *            the name of the Stus property to query
    	 * @param value
    	 *            the property value to match
    	 * @return List<Stus> found by query
    	 */
    	@SuppressWarnings("unchecked")
    	public List<Stus> findByProperty(String propertyName, final Object value) {
    		logger.info("finding Stus instance with property: " + propertyName
    				+ ", value: " + value);
    		try {
    			final String queryString = "select model from Stus model where model."
    					+ propertyName + "= :propertyValue";
    			Query query = getEntityManager().createQuery(queryString);
    			query.setParameter("propertyValue", value);
    			return query.getResultList();
    		} catch (RuntimeException re) {
    			logger.error("find by property name failed", re);
    			throw re;
    		}
    	}
    
    	public List<Stus> findByStuName(Object stuName) {
    		return findByProperty(STU_NAME, stuName);
    	}
    
    	public List<Stus> findByStuAge(Object stuAge) {
    		return findByProperty(STU_AGE, stuAge);
    	}
    
    	/**
    	 * Find all Stus entities.
    	 * 
    	 * @return List<Stus> all Stus entities
    	 */
    	@SuppressWarnings("unchecked")
    	public List<Stus> findAll() {
    		logger.info("finding all Stus instances");
    		try {
    			final String queryString = "select model from Stus model";
    			Query query = getEntityManager().createQuery(queryString);
    			return query.getResultList();
    		} catch (RuntimeException re) {
    			logger.error("find all failed", re);
    			throw re;
    		}
    	}
    
    	public static IStusDAO getFromApplicationContext(ApplicationContext ctx) {
    		return (IStusDAO) ctx.getBean("StusDAO");
    	}
    }

    5.测试效果如下



    数据库中截图



    以上步骤即是struts、spring、jpa的集成,当然相应的添加、修改、删除操作也是类似的,就不写了


    6.遇到的问题

    严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stusAction' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy21 implementing com.undergrowth.IStusDAO,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'com.undergrowth.StusDAO' for property 'stusDAO'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [$Proxy21 implementing com.undergrowth.IStusDAO,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.undergrowth.StusDAO] for property 'stusDAO': no matching editors or conversion strategy found
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
    	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
    	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
    	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1113)
    	at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1671)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    	at java.lang.Thread.run(Thread.java:722)
    Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy21 implementing com.undergrowth.IStusDAO,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'com.undergrowth.StusDAO' for property 'stusDAO'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [$Proxy21 implementing com.undergrowth.IStusDAO,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.undergrowth.StusDAO] for property 'stusDAO': no matching editors or conversion strategy found
    	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:485)

    上面的错误是说在StusAction进行依赖注入的时候stusDao的类型不匹配,原因在于spring容器在进行注入的时候,为stusDao生成代理对象的时候,采用的是jdk的动态代理,但是jdk的动态代理有一个前提就是,目标对象和代理对象有一个共同的接口,所以会造成类型不匹配


    解决方案如下:



  • 相关阅读:
    BZOJ.1034.[ZJOI2008]泡泡堂(贪心)
    BZOJ.4247.挂饰(背包DP)
    Codeforces.1040E.Network Safety(思路 并查集)
    LOJ.2863.[IOI2018]组合动作(交互)
    BZOJ.3624.[APIO2008]免费道路(Kruskal)
    BZOJ.4237.稻草人(CDQ分治 单调栈)
    BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
    BZOJ.4946.[NOI2017]蔬菜(贪心 离线)
    BZOJ.2660.[BJOI2012]最多的方案(DP)
    BZOJ.3994.[SDOI2015]约数个数和(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275583.html
Copyright © 2011-2022 走看看