SSH0配置-最简单的实例

SSH零配置--最简单的实例

今天没事突然想学习一下SSH的零配置,于是乎在Google上不断的百度,但是结果让人很不爽。大多的不是只有配置文件,就是纯理论,没有一个实例可供参考。

其实我只想弄一个简单的实例看看SSH三者是怎么联系到一起的,搜到的却是一顿的讲细节,真是从学生过来了就忘了做学生的滋味了。悲哀啊!

好吧,我只有自己研究下,终于弄出来这个简单的实例,这里记录主要是供我自己以后参考,如果有人关注就更好了。

 

附件是我的eclipse工程的src目录,lib太大大家自己下吧,缺啥类下啥包,版本尽里有新一点的,应该都可以。

 

下面讲解开始:

 

所谓0配置并不是一个配置文件都没有,基本配置是有的,比如DataSource你总要配置吧,要不然从哪去联数据库啊。

 

三个基本配置文件 web.xml, struts.xml, spring.xml,大家都应该知道怎么放。

一个一个贴出,大部分都跟正常的SSH配置一样,大家只需浏览一下,有注释的地方请看一看。

web.xml -- 最基本的SSH整合配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- Struts Core Filter -->
	<filter>
		<filter-name>struts2</filter-name>
		<!--
			OR:
			org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
		-->
		<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>struts-default.xml,struts-plugin.xml,struts.xml</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Struts Cleanup Filter -->
	<filter>
		<filter-name>struts2-cleanup</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2-cleanup</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Spring Listener -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml</param-value>
	</context-param>

	<!-- 解决Hibernate Session延迟加载问题 -->
	<filter>
		<filter-name>OpenSessionInView</filter-name>
		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>OpenSessionInView</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Character Encoding filter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
</web-app>

 

struts.xml --- 注意后面的常量,我这里加入了json插件,使用了global result,这样做是很有好处的,文章最后再说说。

<?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>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.i18n.reload" value="true" />
	<constant name="struts.configuration.xml.reload" value="true" />
	<constant name="struts.convention.default.parent.package" value="root"/>
	<!-- <constant name="struts.convention.package.locators" value=""/> -->
	<!-- 这里使用了JSON插件,下载加上吧,很有好处的 -->
	<package name="root" namespace="/" extends="json-default">
		<global-results>
			<result name="json" type="json" />
		</global-results>
	</package>
</struts>

 

spring.xml --- 大致就是配置数据源,事务,使用注释的hibernate session工厂,自身使用注释的配置

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                       http://www.springframework.org/schema/context
                       http://www.springframework.org/schema/context/spring-context-2.5.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">

	<!-- data source 基本的连接池 -->
	<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:3306/xjdwebtool"/>
		<property name="username" value="root"/>
		<property name="password" value="root"/>
		
		<property name="initialSize" value="5"/>
		<property name="maxActive" value="50"/>
		<property name="maxIdle" value="10"/>
		<property name="maxWait" value="20"/>
		<property name="minIdle" value="1"/>
	</bean>
	
	<!-- Hibernate3 Session Factory: 注意这里使用的是AnnotationSessionFactoryBean -->
	<!-- 这里配置后就可以省去Hibernate的与持久类对应的.hbm.xml文件了,持久类使用注释@Entity-->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
			</props>
		</property>
		<!-- 这个属性指明了使用注释的持久类的包-->
		<property name="packagesToScan">
			<list>
				<value>com.xjdwebtool.bean</value>
			</list>
		</property>
	</bean>
	
	<!-- 用于在Dao中使用 -->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	
	<!-- Transaction Manager 事务管理器-->
	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	
	<!-- Annotation Driver: 使用注释事务管理-->
	<!-- 这里配置后将使用注释事务方式,不用再在这个XML文件中配置事务代理对象了 -->
	<tx:annotation-driven transaction-manager="txManager"/>
	
	<!-- 这里配置后就不用再使用bean标签配置bean了 -->
	<context:annotation-config />
	<!-- 去哪个包扫描生成bean -->
 	<context:component-scan base-package="com.xjdwebtool.*" /> 
	
</beans>

 

这些配置文件看着吓人,都是基本的,配置就这么多了,下面就是注释类了。

 

我这里使用了一个简单的例子,总共4个类,他们的调用关系是:

 

TestAction(Struts的Action类)--调用-->TestService(事务层)--调用-->TestDao(Dao类,操作数据库)
TestBean(持久化Bean类)

 一个一个贴出各个类,注意他们的注释

TestBean.java --- 就两个属性,一个id, 一个title

package com.xjdwebtool.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "test")
public class TestBean {
	@Id
	@Column(name = "id")
	private long id;

	@Column(name = "title", length = 50)
	private String title;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
}
 

TestAction.java --- 调用TestService的findById查询一个TestBean

package com.xjdwebtool.action;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.xjdwebtool.bean.TestBean;
import com.xjdwebtool.service.TestService;

//Struts Action 相当于<bean id="testAction" class="..."/>
@Component("testAction")
public class TestAction {
	private static Logger log = Logger.getLogger(TestAction.class);
	
	//这里使用类型匹配自动装配,如果有多个,增加使用@Qualifier("testService")指定bean名
	@Autowired
	private TestService service;
	
	private TestBean bean;

	public String execute()  {
		log.info("TestAction 调用成功");
		bean = service.findById(1L);
		log.info("数据查询成功:title='" + bean.getTitle() + "'");
		return "json";
	}
	
	//这里只有这一个get方法,在返回的json结果中只有这个对象
	public TestBean getBean() {
		return bean;
	}
}
 

TestService.java ---  该类可以不用,只是为了增加一个事务层而已

package com.xjdwebtool.service;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.xjdwebtool.bean.TestBean;
import com.xjdwebtool.dao.TestDao;

@Component("testService")
public class TestService {
	private static Logger log = Logger.getLogger(TestService.class);
	
	@Autowired
	private TestDao dao;
	
	@Transactional(readOnly=true)//这里配置事务
	public TestBean findById(long id) {
		log.info("TestService 调用成功");
		return dao.findById(id);
	}
}

 

TestDao.java --- Dao访问数据库

package com.xjdwebtool.dao;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.xjdwebtool.bean.TestBean;

@Component("testDao")
public class TestDao {
	private static Logger log = Logger.getLogger(TestDao.class);
	
	@Autowired //这个属性使用在配置文件中配置的bean
	private HibernateTemplate hibernate;

	public TestBean findById(long id) {
		log.info("TestDao 调用成功");
		return (TestBean) hibernate.get(TestBean.class, id);
	}
}

 

最后启动Tomcat吧,在浏览器输入地址,我的为:

<a>http://localhost:8080/xjdwebtool2/test</a>

 请求的Action是test。我的Log输出为(level 为info):

2011-07-13 16:14:31  INFO TestAction: 26 - TestAction 调用成功
2011-07-13 16:14:32  INFO TestService: 20 - TestService 调用成功
2011-07-13 16:14:32  INFO TestDao: 20 - TestDao 调用成功
Hibernate: 
    select
        testbean0_.id as id0_0_,
        testbean0_.title as title0_0_ 
    from
        test testbean0_ 
    where
        testbean0_.id=?
2011-07-13 16:14:32  INFO TestAction: 28 - 数据查询成功:title='This is data from mysql'

 从而可以看出,这个test是自动配置的且调用成功了。浏览器会提示要保存一个文件,就是我们的json格式的文本,保存下来打开,我的结果为:

{"bean":{"id":1,"title":"This is data from mysql"}}

 

OK,实例完了。注意这里的test是没有在文件中配置的,完全是由struts的自动查找+spring的注释完成的。

 

这里说一下实例中可能遇到的情况:一个是会提示一些类找不到,上网搜一下这个类,就知道你缺什么包,其中有些是因为版本的问题。如我开始用的Hibernate3.3.2就会提示一个AnnotationConfiguration类找不到,这个版本确实没这个类,于是我就用了Hibernate3.6; 另一个是注释@Component("BeanName")时,BeanName不要乱写,这个就是<bean/>的id。对于struts使用的是自动查找,如我们请求的test,struts会搜索类似testAction的bean,这个就请参考其它资料吧,我也不是十分清楚。

 

最后说一下struts的result配置。因为这里不再配置action到xml中,所以对action的返回结果使用了globalResult的方式。还有又不能为每一个action去配置一个globalResult(如果这么做我认为就失去了struts零配置的意义,这里很多人建议对struts不要使用零配置的方式),所以这里一个好的解决方案是不要让action返回特定的html,而是返回xml格式或json格式的文本。这样的话,在globalResult只需配置这两个类型的结果就行了。这就是我为什么引入json插件的原因。xml应该也有插件吧,快下班了,要赶班车就不搜了。

 

=======================================================================

2011-7-14:

 

查阅了一些资料,对原码进行了下更新,如action的@Scope应该为prototype,使用@Controller,@Service,@Repository等。附件 src_修订2.rar

 

再次上传整个工程包括jar包。

1 楼 u177734357 2011-07-14  
就是没看到 当action为ActionSupport子类时 action中的方法 这么注解
2 楼 u177734357 2011-07-14  
过几天我发过完整的 ssh+ibatis+ext实现的项目上来
3 楼 b_l_east 2011-07-15  
u177734357 写道
过几天我发过完整的 ssh+ibatis+ext实现的项目上来

期待,不用太多内容,一个模板就行!

u177734357 写道
就是没看到 当action为ActionSupport子类时 action中的方法 这么注解

这个一样注释吧,没什么不同,但是对于dao继承HibernateDaoSupport,如何注释那个setHibernateTemplate或setSessionFactory我没有办法。这两个方法都是final的不能重写。不过我重新加一个set方法然后调用它们的方就行了。对这个你知道多少啊,交流交流下啊,我是不太懂的。
4 楼 epic2005 2011-10-27  
附源代码的银 都是好银... SSH0配置-最简单的实例
5 楼 cengjing0616k 2012-03-31  
我搭建后 启动tomcat咋报
Unable to load configuration. - [unknown location]
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:371)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:415)
at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:190)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4363)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: Unable to locate parent package [root] - [unknown location]
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.getPackageConfig(PackageBasedActionConfigBuilder.java:952)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:601)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:336)
at org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:215)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
... 30 more

兄弟们。帮忙看下吧 网上搜了好久 都没能解决,我感觉这是不是jar冲突啦?
6 楼 b_l_east 2012-04-05  
cengjing0616k 写道
我搭建后 启动tomcat咋报
Unable to load configuration. - [unknown location]
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:371)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:415)
at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:190)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4363)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: Unable to locate parent package [root] - [unknown location]
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.getPackageConfig(PackageBasedActionConfigBuilder.java:952)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildConfiguration(PackageBasedActionConfigBuilder.java:601)
at org.apache.struts2.convention.PackageBasedActionConfigBuilder.buildActionConfigs(PackageBasedActionConfigBuilder.java:336)
at org.apache.struts2.convention.ClasspathPackageProvider.loadPackages(ClasspathPackageProvider.java:53)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:215)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
... 30 more

兄弟们。帮忙看下吧 网上搜了好久 都没能解决,我感觉这是不是jar冲突啦?


不好意思,很久没弄了,已经忘了。现在玩SpringMVC + Spring + MyBatis了。
7 楼 afeifqh 2012-05-14  
lz,web.xml文件里OpenSessionInView 过滤器的配置应该配置在 struts过滤器的前面,否则在没有配置事务的情况下,会出现错误的。。。当然,正确配置了事务,就没有这个问题。
8 楼 wms6891 2012-05-26  
这个后台倒是差不多,我想问一下怎么对应前台跳转的页面呢?
比如说我一个提交要跳到另一个页面中去,action中的return “页面”怎么与webroot下的页面对应?