在java web开发中,struts, springs和mybatis是常用的框架。下面通过一个简单的登录功能对这三个框架学习。
1.下载需要的框架。
struts: http://struts.apache.org/
spring: http://www.springsource.org/download/
mybatis: http://code.google.com/p/mybatis/
2.使用eclipse建立dynamic web工程 SimpleStrutsSpringMybatis
3.编写web.xml配置文件,添加spring监听,log4j监听和struts过滤器
<?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"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>SimpleStrutsSpringMybatis</display-name>
<description>Struts spring mybatis intergaration</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
4. 编写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.i18n.encoding" value="UTF-8"></constant>
<package name="learn" extends="struts-default">
<interceptors>
<interceptor name="loginedCheck"
class="simple.learn.ssb.interceptor.LoginedCheckInterceptor" />
</interceptors>
<action name="login" class="loginAction" method="logining">
<result name="success">/jsp/success.jsp</result>
<result name="error">jsp/error.jsp</result>
<result name="input">/index.jsp</result>
</action>
<action name="loginout" class="loginAction" method="loginout">
<result name="input">/index.jsp</result>
</action>
</package>
</struts>
5. 完成基础配置后,编写java代码了,使用action,entity,mapper,service和interceptor包来存放对象java代码。
创建实体对象:User.java
package simple.learn.ssb.entity; import java.io.Serializable; public class User implements Serializable{ private static final long serialVersionUID = 1L; private String username; private String password; 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; } }
LoginAction.java, 在这使用了模型作为参数
package simple.learn.ssb.action; import java.util.Map; import javax.annotation.Resource; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ModelDriven; import simple.learn.ssb.entity.User; import simple.learn.ssb.service.UserOperation; public class LoginAction implements ModelDriven<User> { private User user = new User(); @Resource private UserOperation uop ; public void setUop(UserOperation uop) { this.uop = uop; } public String logining() throws Exception { if(null!=uop.getlogin(user.getUsername(), user.getPassword())) { System.out.println("login success!"); ActionContext actionContext = ActionContext.getContext(); Map<String, Object> session = actionContext.getSession(); session.put("logined", "logined"); } else { return "error"; } return "success"; } public String loginout() throws Exception { return "input"; } @Override public User getModel() { // TODO Auto-generated method stub return user; } }
编写数据库映射接口,LoginMapper.java,这只有一个登录方法
package simple.learn.ssb.mapper; import simple.learn.ssb.entity.User; public interface LoginMapper { public User loginbyUsernameAndPassword(User user); }
编写LoginMapper.xml文件,和LoginMapper.java放在相同目录下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="simple.learn.ssb.mapper.LoginMapper">
<cache/>
<select id="loginbyUsernameAndPassword" parameterType="simple.learn.ssb.entity.User" resultType="user">
select username, password
from login where
username=#{username} and password=#{password}
</select>
</mapper>
编写service类
package simple.learn.ssb.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import simple.learn.ssb.entity.User; import simple.learn.ssb.mapper.LoginMapper; @Service public class UserOperation { @Autowired private LoginMapper loginMapper; public User getlogin(String username,String password) { User user = new User(); user.setUsername(username); user.setPassword(password); return loginMapper.loginbyUsernameAndPassword(user); } }
编写拦截器进行登录验证,LoginedCheckInterceptor.java
package simple.learn.ssb.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class LoginedCheckInterceptor extends AbstractInterceptor{ private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation ai) throws Exception{ if(ai.getInvocationContext().getSession().containsKey("logined")){ return ai.invoke(); } else { return "input"; } } }
编写LogAspect.java,进行方法调用日志信息捕获
package simple.learn.ssb.interceptor; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class LogAspect { public Logger logger = Logger.getLogger(LogAspect.class); @Pointcut("execution(* simple.learn.ssb.service.*.*(..))") public void anyMethod() { } @Before(value = "anyMethod()") public void myBeforAdvice(JoinPoint joinpoint) { String classAndMethod = joinpoint.getTarget().getClass().getName() + "类的" + joinpoint.getSignature().getName(); logger.info("前置通知:" + classAndMethod + "开始执行"); } @AfterReturning(value = "anyMethod()") public void myAfterReturningAdvice(JoinPoint joinpoint) { String classAndMethod = joinpoint.getTarget().getClass().getName() + "类的" + joinpoint.getSignature().getName(); logger.info("后置通知:" + classAndMethod + "方法正确执行"); } @AfterThrowing(value = "anyMethod()", throwing = "e") public void myAfterThrowingAdvice(JoinPoint joinpoint, Exception e) { String classAndMethod = joinpoint.getTarget().getClass().getName() + "类的" + joinpoint.getSignature().getName(); logger.info("异常通知:" + classAndMethod + "方法异常" + e.getMessage()); } @After(value = "anyMethod()") public void myAfterAdvice(JoinPoint joinpoint) { String classAndMethod = joinpoint.getTarget().getClass().getName() + "类的" + joinpoint.getSignature().getName(); logger.info("最终通知:" + classAndMethod + "方法执行结束"); } @Around(value = "anyMethod()") public Object myAroundAdvice(ProceedingJoinPoint pjp) throws Throwable { long begintime = System.currentTimeMillis(); Object result = pjp.proceed(); long endtime = System.currentTimeMillis(); String classAndMethod = pjp.getTarget().getClass().getName() + "类的" + pjp.getSignature().getName(); logger.info("环绕通知:" + classAndMethod + "方法执行结束,耗时" + (endtime - begintime) + "毫秒"); return result; } }
6. 编写applicationContext.xml,配置applicationContext.xml是一个相当问题比较多的文件。我参考了mybatis和spring整合的jpetstore例子。http://code.google.com/p/mybatis/downloads/list?can=3&q=Product%3DSample
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="jdbcUrl"
value="jdbc:sqlserver://127.0.0.1:1433;databaseName=jhsy1" />
<property name="user" value="sa" />
<property name="password" value="123456" />
<property name="initialPoolSize" value="10" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="30" />
<property name="acquireIncrement" value="10" />
<property name="maxIdleTime" value="10" />
<property name="maxStatements" value="0" />
</bean>
<!-- 数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
<property name="url"
value="jdbc:sqlserver://127.0.0.1:1433;databaseName=jhsy1"></property>
<property name="username" value="sa"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="c3p0DataSource" />
<property name="typeAliasesPackage" value="simple.learn.ssb.entity" />
</bean>
<!-- 声明式事务 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<!--
enable component scanning (beware that this does not enable mapper
scanning!)
-->
<context:component-scan base-package="simple.learn.ssb.service" />
<!-- enable autowire -->
<context:annotation-config />
<aop:aspectj-autoproxy />
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="simple.learn.ssb.mapper" />
</bean>
<bean id="loginAction" class="simple.learn.ssb.action.LoginAction"></bean>
<bean id="loginAspect" class="simple.learn.ssb.interceptor.LogAspect"></bean>
</beans>
项目jar包过多,分为四个压缩包上传,项目压缩包中剔除了jar包,将所有jar包放回WEB-INF下lib中,即可运行项目。