这个示例通过一个spring mvc用户登录的示例来学习是如何进行spring web开发的。
业务功能:用户通过登录页面输入用户名和密码,提交验证,登录成功则更新用户登录信息(登录ip,最后访问时间,积分+5)同时记录用户登录成功日志。整个demo分为四层,每层对应一个对立的配置文件。
持久层对象,也是域对象也叫实体。
持久层:spring整合多种流行ORM框架,如hibernate,ibatis等,此demo采用spring JDBC,通过调用org.springframework.jdbc.core.JdbcTemplate完成DAO的实现。配置文件命名(app-dao.xml)
业务层:以接口的方式,调用持久层DAO。接口的方式可增加代码的灵活性,同时有利于项目的管理以及变更。配置文件命名(app-service.xml)
表现层:采用spring mvc框架。层次与struts类似,不过要手动配置Spring MVC地址映射,控制器,以及URL与控制器映射定义。个人认为初次配置觉得较struts而言麻烦点,但很灵活。可以通过配置手动配置请求地址,响应地址。关于整个demo将上传,下面解释下各配置文件。
1.在spring中装配DAO(这里以userlogin-dao.xml为例)
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" >
- <beans>
- <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/test"/>
- <property name="username" value="root"/>
- <property name="password" value="root"/>
- </bean>
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
- <property name="dataSource" ref="dataSource"/>
- </bean>
- <bean id="userDao" class="com.me.dao.imp.UserDaoImp">
- <property name="jdbcTemplate" ref="jdbcTemplate"/>
- </bean>
- <bean id="userLogDao" class="com.me.dao.imp.UserLogDaoImp">
- <property name="jdbcTemplate" ref="jdbcTemplate"/>
- </bean>
- </beans>
这里主要想说的的是jdbcTemplate,因为此demo采用spring JDBC实现的持久层,而spring JdbcTemplate封装了jdbc的操作,本身只需要一个DataSource.
2.配置业务层(这里以userlog-service.xml为例)
...
- <beans>
-
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"/>
- </bean>
-
- <bean id="userServiceTarget" class="com.me.service.imp.UserServiceImp">
- <property name="userDao" ref="userDao"/>
- <property name="logDao" ref="userLogDao"></property>
- </bean>
-
- <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager" ref="transactionManager"></property>
- <property name="target" ref="userServiceTarget"/>
-
- <property name="transactionAttributes">
- <props>
- <prop key="findUserByUserName">
- PROPAGATION_REQUIRED,readOnly
- </prop>
- <prop key="checkUser">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="loginSuccess">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- </beans>
大家知道凡是操作数据库都要涉及到事务处理,而利用spring我们将不用在代码实现中担心这一点,通过spring声明式事务配置即可。这里需要额外提一下transactionAttributes是定义目标业务类那些方法需要业务的支持以及事务控制属性。PROPAGATION_REQUIED是用得最多的事务传播类型,表示业务方法在当前线程中查看是否有事务,如果有,就利用这个事务,否则就创建一个新事务。readOnly表示是只读事务,可以提高运行效率。此外,在配置方法名时,可实用“*”,不过不指定方法就表示对所有方法进行事务管理。
3.配置Spring MVC 框架
1)修改web.xml,以便web容器启动时自动启动Spring容器。
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:userlogin-dao.xml,classpath:userlog-service.xml</param-value>
- </context-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
2)配置spring mvc地址映射,与struts一样,spring mvc也需要一个servlet截获URL,修改web.xml.
- <servlet>
- <servlet-name>userlogin</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>2</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>userlogin</servlet-name>
- <url-pattern>*.html</url-pattern>
- </servlet-mapping>
需要说明的像struts一样,spring也需要一个类似struts-config.xml的配置文件,但命名可有讲究的哦,要采用<servlet-name>-servlet.xml以这个例子来说则需要在/WEB-INF目录下创建一个userlogin-servlet.xml,但这个配置文件无需在web.xml配置上下文参数,因为spring mvc的servlet会自动将userlogin-servlet.xml与spring其他配置文件(userlogin-dao.xml,userlog-service.xml)进行拼装。
3)在配置文件中声明控制器(userlogin-servlet.xml)
- <beans>
- <bean name="loginController" class="com.me.web.LoginController">
- <property name="userService" ref="userService"></property>
- </bean>
- <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="/loginController.html">loginController</prop>
- </props>
- </property>
- </bean>
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/jsp/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
这个配置说明/loginController.html的请求将交由loginController类处理,处理结果返回一个ModelandView("param1","param2",param3)对象,带有三个参数,分别表示重定向视图逻辑名,保存在request范围内的一个变量名,变量的值。而viewResolver中就是在配置重定向的页面,它的url是:prefix+parma1+suffix.此demo中登录成功后将重定向到{basepath}/jsp/main.jsp
最后处理下乱码问题。此demo采用的是uft-8的字符编码,后来还是出现了乱码,于是调用spring 中的过滤器进行过滤。修改web.xml.
- <filter>
- <filter-name>encodingFilter</filter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>utf8</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>/jsp/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>*.html</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>*.jsp</url-pattern>
- </filter-mapping>