《跟我一起做J2EE版Blog–jPress》6(Spring集成Struts2,打通第一个Action)

    连载第六集,前面讲了Spring和Hibernate的集成,集成的方法主要是Spring中配置好datasource和SessionFactory的bean,在Dao中注入sessionFactory对数据库进行操作。
    这一讲来集成Spring和Struts,并且打通第一个action,在action中使用hibernate并返回JSP。Struts框架的作用是将项目的逻辑层和视图层分离出来,实现MVC。Struts可以减少jsp文件,因为JSP这玩意儿的存在将视图和逻辑混杂到令人发指的程度,所以我是坚决不会在JSP页面中写任何JAVA语句的(顺便说一句,jPress项目甚至不准备写任何JSP文件,视图层用Freemarker设计,这个模板引擎太强大了,可以说使用Struts不配合上Freemarker那就是糟蹋东西了)。Spring和Struts这二者的集成方式主要靠编辑web.xml文件。我们需要在web.xml中添加几个监听器和过滤器,并且从marven中央库中引入一个struts2-spring-plugin的jar包。下面是个插件包的marven描述:
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>2.3.1.2</version>
</dependency>
    接下来编辑web.xml,添加监听器和过滤器:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="3.0"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<display-name>jpress</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	
	<context-param>
		<description>指定Spring的bean配置文件</description>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>

	<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>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    </filter>
    
    <filter-mapping>
    	<filter-name>openSessionInViewFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>

  <!-- define a JspSupportServlet Object -->
  <servlet-name>JspSupportServlet</servlet-name>
	  <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
	  <!-- setting JspSupportServlet auto start -->
	  <load-on-startup>1</load-on-startup>
  </servlet>
	
</web-app>
    这样jPress就具有Struts的能力了,通过web.xml中监听器和触发器的配置,我们能够在struts的action中使用spring容器中的bean。在MyEclipse中为项目添加Struts特性后,会得到一个struts.xml的配置文件,下面我们来配置一个测试action,在这个测试action中我们调用数据层的方法,数据操作结束后,返回信息给JSP。首先编写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 name="struts.custom.i18n.resources" value="com.flyding.jpress.messages"/>  

    <package name="default" namespace="/" extends="struts-default">
    	<default-action-ref name="hello"></default-action-ref>
    	<global-results>
    		<result name="error" type="freemarker">/WEB-INF/views/error.ftl</result>
    	</global-results>
        <action name="hello" class="com.flyding.jpress.actions.TestAction">
            <result>
                /index.jsp
            </result>
        </action>
    </package>

</struts>    
    这段配置文件做了一个名叫hello的action路由,当用户在浏览器中访问/hello这个地址时会被struts截取,struts会将请求发送到配置好的com.flyding.jpress.actions.TestAction这个类中,并寻找execute这个方法,根据execute方法返回的字符串判断这次请求继续往哪儿流,如果execute返回SUCCESS,则往index.jsp流,如果execute返回ERROR,则往/WEB-INF/views/error.ftl这个模板文件流,模板文件我们下一章再讲,今天先讲以JSP返回显示信息的方法。下面是TestAction的JAVA文件:
public class TestAction extends ActionSupport {
	private static final long serialVersionUID = 5425386805840506298L;	
	
	//@Autowired
	//private LinkDao linkDao;
	@Autowired
	private UserDao userDao;
	
	User user;
	String exception;

	@Override
	public String execute() {		
		try {
			userDao.changePassword((long)1, "8215085", "8215083");
		} catch (UserNoMatch e) {
			this.exception=e.getMessage();
			return ERROR;
		}
		return SUCCESS;
	}
	
	public User getUser(){
		return this.user;
	}
	public String getException(){
		return this.exception;
	}
}
    在Action中,我们用@Autowired注解标明这个UserDao类型的userDao变量是需要Spring给我们自动注入的,虽然。。。虽然有一些说法说是不建议在属性定义的时候autowire,而是应该在public get方法上进行织入,但是我个人还是比较习惯直接织入的,可以省去很多getter&setter,性能上应该没有什么差异。同时我们需要回到上一讲的UserDaoImpl类中,在这个类开头部分使用@Component("userDao")注解标明这个类将作为一个名叫userDao的组件保存进Spring容器中供上层逻辑调用。Action中的execute方法调用了UserDao的修改密码方法,这个方法需要用户ID,原始密码,新密码三个参数,如果ID跟原始密码错误则抛出验证失败的异常,这种做法也是我个人比较提倡的做法,采用自定义异常的方法取代项目逻辑中if else以及switch等语句,这将提高项目的代码质量
    启动Tomcat或者Resin,我个人比较喜欢在项目开发阶段使用Resin不断调试,因为Resin是最快的JAVA WEB容器,效率很高;在服务器部署的时候使用Tomcat,因为Tomcat性能稳定,可以作为操作系统的service,并且可以通过配置NIO模式、GZip模式等提高Tomcat的各项性能
浏览器中输入http://localhost:8080/jPress/hello,这时候WEB容器判断出hello是一个action名,于是将请求转发到TestAction并寻找其中的excute方法,spring会适时地介入并提供一个userDao注入给action使用,这个userDao在WEB容器启动时已经定义好了,是一个UserDaoImpl的对象,其中使用的sessionFactory也是Spring为他提供的。action执行OK后根据逻辑会返回SUCCESS或者ERROR,根据Struts中的定义,如果返回SUCCESS则内部跳转到index.jsp,在index.jsp中我们使用struts标签就能看到处理结果了。
    正如我所说,今天只是打通WEB容器与SSH三者之间呃脉络,测试成功后我们会抛弃JSP的,因为我太喜欢Freemarker了。打通脉络后,下一章我们将先暂停JAVA端的开发,先跟着我去Dreamweaver和Photoshop上去设计DIV+CSS,我们要为jPress设计第一套默认皮肤,然后将默认皮肤转化成模板ftl文件。

posted on 2012-03-20 00:00  newflypig  阅读(394)  评论(0编辑  收藏  举报

导航