SSH combat OA 02: SSH framework construction

The previous section explained the project functions, design and coding specifications, etc. This section is mainly to build the environment for the project, mainly to build the SSH development environment, log printing and unit test Junit environment.

SSH integration

Introduction to SSH

SSH is an integrated framework of struts+spring+hibernate, and it is a popular open source framework for web applications.
The system integrating the SSH framework is divided into four layers in terms of responsibilities: presentation layer, business logic layer, data persistence layer and domain module layer to help developers build web applications with clear structure, good reusability and easy maintenance in a short period of time program. Among them, Struts is used as the overall infrastructure of the system, which is responsible for the separation of MVC. In the model part of the Struts framework, it controls the business jump, uses the Hibernate framework to provide support for the persistence layer, and Spring manages struts and hibernate. The specific method is: using the object-oriented analysis method to propose some models according to the requirements, implement these models as basic Java objects, then write the basic DAO (Data Access Objects) interface, and give the DAO implementation of Hibernate, which is implemented using the Hibernate architecture. The DAO class implements the conversion and access between Java classes and the database, and finally managed by Spring, managing struts and hibernate.

--Baidu Encyclopedia

Required jar package

The first step in using a framework written by others is to import the required packages. For example, when jQuery is referenced, the jquery.js package needs to be imported. When using the SSH framework, the following jar packages need to be imported:
- antlr-2.7.6.jar
- aspectjrt.jar
- aspectjweaver.jar
- c3p0-0.9.1.jar
- cglib-nodep-2.1_3.jar
- commons-beanutils-1.7.0.jar
- commons-codec.jar
- commons-collections-3.1.jar
- commons -fileupload-1.2.1.jar
- commons-io-1.3.2.jar
- commons-lang-2.5.jar
- commons-logging.jar
- dom4j-1.6.1.jar
- ezmorph-1.0.3.jar
- freemarker -2.3.15.jar
- hibernate-jpa-2.0-api-1.0.0.Final.jar
- hibernate3.jar
- javassist-3.12.0.GA.jar
- json-lib-2.1-jdk15.jar
- jstl-1.2 .jar
- jta-1.1.jar
- log4j-1.2.15.jar
- mysql-connector-java-5.1.5-bin.jar
- ognl-2.7.3.jar
- slf4j-api-1.5.0.jar
- slf4j-log4j12-1.5.0.jar
- spring-test.jar
- spring.jar
- struts2-core-2.1.8.1.jar
- struts2-json-plugin-2.1.8.1.jar
- struts2-spring-plugin-2.1.8.1.jar
- xwork-core-2.1.6.jar

New Project

  1. Create a new project, type Web Project, set the default encoding to UTF-8, and create the following folders:
    Source Folder
     –src : project source code
     –config : configuration file
     –test : unit test
  2. Common folder
     – WebRoot/style css and pictures and other files
     – WebRoot/script js script file
     – WebRoot/WEB-INF/jsp jsp page file
  3. Package structure
    a. Entity
       com.shizongger.oa.domain
    b. Dao
       com.shizongger.dao Dao interface
       com.shizongger.oa.dao.impl Dao implementation class
    c. Service
       com.shizongger.oa.service Service interface
       com.shizongger. oa.service.impl Service implementation class
    d. View(Struts2)
       com.shizongger.oa.strtus2.action
    e. Other
       com.shizongger.oa.util tool classes

The project structure after the successful creation is as follows:
write picture description here

configuration item

1. First configure the filter of Struts2, the content of web.xml is as follows:

<?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"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <!-- 配置Spring的监听器,用于初始化ApplicationContext对象 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>

    <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>index.html</welcome-file>
    </welcome-file-list>
</web-app>

The content of the listener node is the listener of the Srping container, and the filter is the url interception of Struts2. The corresponding interceptor for Struts2 is:

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

The intercepted address is:

/*

In this way, each request address will go through our interceptor in the future, so that the action can be intercepted.

2. Configure the Struts.xml file

<?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" />
    <!-- 配置扩展名为action -->
    <constant name="struts.action.extension" value="action" />

    <package name="default" namespace="/" extends="struts-default">
        <!-- 测试用的action,当与Spring整合后,class属性写的就是Spring中bean的名称 -->
        <action name="user" class="userAction">
            <result name="welcome">/WEB-INF/jsp/welcome.jsp</result>
            <result></result>
        </action>

    </package>
</struts>

Here we use one of our action: userAction

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.shizongger.oa.domain.User;
import com.shizongger.oa.service.UserService;

@Controller("userAction")
@Scope("prototype")
public class UserAction extends ActionSupport {

    @Autowired
    private UserService userService;

    @Override
    public String execute() throws Exception {
        User user = new User();
        user.setName("admin");
        userService.add(user);

        return "welcome";
    }
}

This action belongs to the singleton mode, and uses the @Controller("userAction") annotation to hand over our action to the spring container for management, so there is no need to write the full name of the action in the action element of Struts.xml, only userAction That's enough, it will automatically find the honored action in the container.

3. Configure the Hibernate configuration file hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

    <!-- 数据库信息(连接信息写到spring的配置文件中) -->
    <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
    <!-- 其他配置 -->
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>

    <!-- 导入映射配置 --> 
    <mapping resource="com/shizongger/oa/domain/User.hbm.xml" />

</session-factory>
</hibernate-configuration>

Since it needs to be integrated with Spring, the core information of hibernate is delivered to the configuration file of spring. It is enough to configure the database type of the connection, whether to print out sql, and how hibernate creates database tables. By the way, there is also the location of hbm.xml corresponding to each table.

4. Spring's configuration file applicationContext.xml

<?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: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/tx 
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <!-- 自动扫描与装配bean -->
    <context:component-scan base-package="com.shizongger.oa" />

    <!-- 加载外部的properties配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据库连接池(c3p0) -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 基本信息 -->
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="user" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <!-- 其他配置 -->
        <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize" value="3"></property>
        <!--连接池中保留的最小连接数。Default: 3 -->
        <property name="minPoolSize" value="3"></property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="5"></property>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3"></property>
        <!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
        <property name="maxStatements" value="8"></property>
        <!-- maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
        <property name="maxStatementsPerConnection" value="5"></property>
        <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800"></property>
    </bean>

    <!-- 配置SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
    </bean>

    <!-- 配置声明式的事务管理(采用基于注解的方式) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

The configuration file of this spring is mainly configured with the automatic scanning path, the location of the properties file of jdbc, and the main information of the database connection pool (c3p0).

The integration of spring and hibernate, our sessionFactory transaction with Dao layer is delivered to spring for hosting.

5. Database connection information file: jdbc.properties

jdbcUrl     = jdbc:mysql:///oa
driverClass = com.mysql.jdbc.Driver
username    = root
password    = root

Here I have installed my mysql database in my ubuntu system and created my oa database with the following sql statement.

    mysql> create database oa default character set utf8;
    Query OK, 1 row affected (0.03 sec)
    mysql> show create database oa;
    +--------------+-----------------------------------------------------------------------+
    | Database     | Create Database                                                       |
    +--------------+-----------------------------------------------------------------------+
    | oa | CREATE DATABASE `oa` /*!40100 DEFAULT CHARACTER SET utf8 */ |
    +--------------+-----------------------------------------------------------------------+
    1 row in set (0.02 sec)

The meaning of the first sentence of sql is to create a database oa whose default encoding is utf-8, and the meaning of the second sentence of sql is to display the encoding of the database just created. Apparently the database I created is exactly what I need.

6. Configuration log4j.proprites for log4j log printing

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
#log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
#log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

Here it is temporarily set as the info level. The log has 5 levels, namely debug, info, warm, error, fatal. Generally, during the development process, we should output and print the debug level, which is helpful for us to observe the value of the variable. The above is defined as the info level, and we want to change it in the following project.

Integration Testing

Once the framework is set up, we can run integration tests on it. We directly use the userAction mentioned in the appeal to test the project function.
userAction

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.shizongger.oa.domain.User;
import com.shizongger.oa.service.UserService;

@Controller("userAction")
@Scope("prototype")
public class UserAction extends ActionSupport {

    @Autowired
    private UserService userService;

    @Override
    public String execute() throws Exception {
        User user = new User();
        user.setName("admin");
        userService.add(user);

        return "welcome";
    }
}

The next step is to create userService and its implementation class userServiceImpl
userServcie interface

import com.shizongger.oa.domain.User;

public interface UserService {
    public void add(User user);
}

userServiceImpl implementation class

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shizongger.oa.dao.UserDao;
import com.shizongger.oa.domain.User;
import com.shizongger.oa.service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public void add(User user) {
        try {
            userDao.add(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Need to use our userDao
userDao interface

import com.shizongger.oa.base.BaseDao;
import com.shizongger.oa.domain.User;

public interface UserDao extends BaseDao<User> {

    public User getUserByNamdAndPasswd(String username, String password);
}

UserDaoImple interface implementation class

import com.shizongger.oa.base.BaseDaoImpl;
import com.shizongger.oa.dao.UserDao;
import com.shizongger.oa.domain.User;

public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {

    /**
     * 检测用户的合法性
     */
    @Override
    public User getUserByNamdAndPasswd(String username, String password) {
        return null;
    }

}

We also need our mapping of entities. In order to facilitate testing, we only need to give our User entity an id and a name attribute.

public class User {
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

User's hibenate mapping entity: user.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.shizongger.oa.domain">

    <class name="User" table="itcast_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>

</hibernate-mapping>

If you do not add the location of this xml in hibernate.cfg.xml, an error will be reported, or if you refer to this case and the entity is not user, you need to add the following content in hibernate.cfg.xml:

<!-- 导入映射配置 --> 
<mapping resource="com/shizongger/oa/domain/你的实体名称.hbm.xml" />

At this point, you can start your project by typing in your browser:

localhost:8080/MyOa/user

If you can jump to your welcome.jsp, it means that we have no problem with Spring and Struts. At this time, a user table should be generated in your database, with only two fields: id and nage. If your database also has this The table is generated, then congratulations, our SSH framework environment has been successfully built.

The project code has been hosted to the GitHub project address

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325980954&siteId=291194637
ssh