SSH框架,在JAVA WEB项目中的运用几乎是无处不在,为了对它更加熟悉,练习使用一个最简单的模块记住其中各层的配置和联系。
试题:使用Struts2+Spring+Hibernate开发一个Web用户注册模块,并用log4j生成相应日志。
登录界面
验证
判断用户名
添加用户
生成日志,包含SQL代码
关键点:
1.Struts2开发如何视图(JSP)?如何引入Struts2的标签库并使用?
2.在SSH框架集成的情况下,如何配置Struts.xml?
3.在SSH框架集成的情况下,如何配置applicationContext.xml?
4.在SSH框架集成的情况下,如何配置web.xml?
5.如何搭建SSH的4层构架,也就是POJO层→DAO层→Service层→Action层的构架模块?
6.如何配置log4j在控制台和文件中均生成日志?
下面就按照以上的顺序,展示这个模块的全部代码
一、JSP
UserRegister.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>用户注册</title>
</head>
<body>
<s:actionmessage/>
<s:form method="post" action="register">
<s:textfield name="username" label="用户名"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:submit value="注册"></s:submit>
</s:form>
</body>
</html>
二、配置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>
<package name="struts2" extends="struts-default">
<action name="register" class="userRegister">
<result name="success">/UserRegister.jsp</result>
<result name="input">/UserRegister.jsp</result></action>
</package>
</struts>
三、配置applicationContext.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">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/MySQL">
</property>
<property name="username" value="root"></property>
<property name="password" value="zjx"></property>
</bean>
<!-- 定义SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
<prop key="hibernate.format_sql">
true
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/BBS/pojo/UserSsh.hbm.xml</value></list>
</property></bean>
<!-- 定义HibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/> <!--注入SessionFactory实例对象-->
</property>
</bean>
<!-- 定义HibernateTransactionManager -->
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/> <!--注入SessionFactory实例对象-->
</property>
</bean>
<!--装配数据访问层-->
<bean id="usersshDAOTarget" class="com.BBS.dao.UserSshDAOImpl">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/> <!--注入HibernateTemplate -->
</property>
</bean>
<!-- 为事务代理bean注入事务管理器-->
<bean id="userSshDAO"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="hibernateTransactionManager"/>
</property>
<property name="transactionAttributes"><!-- 设置事务属性 -->
<props>
<!-- 所有的方法,采用required的事务策略 -->
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="target"><!--为事务代理bean设置目标bean -->
<ref bean="usersshDAOTarget"/>
</property>
</bean>
<!--注入DAO层-->
<bean id="userService" class="com.BBS.service.UserServiceImpl">
<property name="userSshDAO" ref="userSshDAO"></property>
</bean>
<!--注入业务逻辑层-->
<bean id="userRegister" class="com.BBS.action.UserRegister" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
</beans>
四、配置web.xml
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 设置Struts2拦截器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 初始化Spring监听 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
五、SSH四层结构与各层代码
POJO层(Beans层)
UserSsh.java
package com.BBS.pojo;
/**
* UserSsh entity. @author MyEclipse Persistence Tools
*/
public class UserSsh implements java.io.Serializable {
// Fields
private String userId;
private String userName;
private String userPasswd;
// Constructors
/** default constructor */
public UserSsh() {
}
/** full constructor */
public UserSsh(String userName, String userPasswd) {
this.userName = userName;
this.userPasswd = userPasswd;
}
// Property accessors
public String getUserId() {
return this.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPasswd() {
return this.userPasswd;
}
public void setUserPasswd(String userPasswd) {
this.userPasswd = userPasswd;
}
}
UserSsh.hbm.xml(映射文件)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.BBS.pojo.UserSsh" table="user_ssh" catalog="mysql">
<id name="userId" type="java.lang.String">
<column name="user_id" />
<generator class="uuid" />
</id>
<property name="userName" type="java.lang.String">
<column name="user_name" />
</property>
<property name="userPasswd" type="java.lang.String">
<column name="user_passwd" />
</property>
</class>
</hibernate-mapping>
DAO层(数据接口层)
UserSshDAO.java
package com.BBS.dao;
import com.BBS.pojo.UserSsh;
public interface UserSshDAO {
public void saveUser(UserSsh userssh); //保存用户
public UserSsh queryByUsername(String username); //根据用户名查找用户
}
UserSshDAOImpl.java
package com.BBS.dao;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.BBS.pojo.UserSsh;
public class UserSshDAOImpl extends HibernateDaoSupport implements UserSshDAO{
public void saveUser(UserSsh userssh) { //保存用户方法
this.getHibernateTemplate().save(userssh);
}
public UserSsh queryByUsername(String username) { //根据用户名查找
@SuppressWarnings("unchecked")
List<UserSsh> list = this.getHibernateTemplate().
find("from UserSsh where userName = ?",username);
if(list.size() == 0){ //判断查询集合是否为空
return null;
}else {
return list.get(0); //返回第一个用户
}
}
}
Service层(业务逻辑层)
UserService.java
package com.BBS.service;
import com.BBS.pojo.UserSsh;
public interface UserService {
public boolean addUser(UserSsh userssh); //新增用户
}
UserServiceImpl.java
package com.BBS.service;
import com.BBS.dao.UserSshDAO;
import com.BBS.pojo.UserSsh;
public class UserServiceImpl implements UserService{
private UserSshDAO userSshDAO; //用户DAO接口引用
public void setUserSshDAO(UserSshDAO userSshDAO) {
this.userSshDAO = userSshDAO;
}
public boolean addUser(UserSsh userSsh) { //增加用户
String username = userSsh.getUserName(); //获得用户名
if(userSshDAO.queryByUsername(username) == null) { //判断用户名是否被占用
userSshDAO.saveUser(userSsh); //保存用户
return true; //保存成功
}else{
return false; //保存失败
}
}
}
Action层(业务控制器层)
UserRegister.java
package com.BBS.action;
import com.BBS.pojo.UserSsh;
import com.BBS.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserRegister extends ActionSupport{
private static final long serialVersionUID = 1L;
private UserService userService;
private String username;
private String password;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
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;
}
public String execute() throws Exception {
UserSsh userssh = new UserSsh(); //创建用户对象
userssh.setUserName(username); //设置用户名
userssh.setUserPasswd(password); //设置密码
if(userService.addUser(userssh)){ //调用增加用户业务方法,判断是否增加成功
this.addActionMessage("添加用户成功!");
}else{
this.addActionMessage("用户被占用,请重新输入用户名");
}
return "success";
}
}
UserRegister-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="username"> <!--指定校验username属性 -->
<field-validator type="requiredstring"> <!--使用必填字符串校验器 -->
<param name="trim">true</param> <!--截断两段空白-->
<message>用户名必须输入</message> <!--校验错误信息 -->
</field-validator>
<field-validator type="stringlength"> <!--使用字符串长度校验器 -->
<param name="minLength">6</param> <!--最小长度-->
<param name="maxLength">15</param> <!--最大长度-->
<message>用户名长度必须在${minLength}到${maxLength}之间</message>
</field-validator>
</field>
<field name="password"> <!--指定校验password属性 -->
<field-validator type="requiredstring"> <!--使用必填字符串校验器 -->
<param name="trim">true</param> <!--截断两段空白-->
<message>密码必须输入</message> <!--校验错误信息 -->
</field-validator>
<field-validator type="stringlength"> <!--使用字符串长度校验器 -->
<param name="minLength">6</param> <!--最小长度-->
<param name="maxLength">15</param> <!--最大长度-->
<message>密码长度必须在${minLength}到${maxLength}之间</message>
</field-validator>
</field>
</validators>
六、日志文件
log4j.properties
# Set root logger level to error
log4j.rootLogger=INFO, Console, File
###### Console appender definition #######
# All outputs currently set to be a ConsoleAppender.
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%-5p [%d{yy.MM.dd HH:mm:ss}][%c]: %m%n
###### File appender definition #######
log4j.appender.File=org.apache.log4j.DailyRollingFileAppender
log4j.appender.File.File=${catalina.home}/webapps/S2SHUser/WEB-INF/logs/s2shuser.log
log4j.appender.File.layout=org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern=%-5p [%d{yy.MM.dd HH:mm:ss}][%c]: %m%n
##Hibernate log begin##
log4j.logger.org.hibernate=info
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.HQL=debug
以上就是SSH框架各层的配置文件与代码,当然在实际代码开发中不是这个顺序
SSH集成的关键是Spring,它为Hibernate生成了会话工厂,添加了事务代理,将Beans一层一层注入到Action中,并用工厂生产Action
虽说开发出的用户注册是Web模块中最简单的一个,但是却可以清晰的看到,SSH框架中各层的联系和相关文件的配置