Fork me on GitHub

SSM:Struts2+Spring+Mybatis Web 项目搭建

目录

  1. 1. 前言
  2. 2. 项目创建
    1. 2.1. 创建新的Maven WebApp项目
    2. 2.2. 配置项目目录
  3. 3. 配置项目
    1. 3.1. 配置数据库连接mysql_db.properties
    2. 3.2. 配置Mybatis Generator
    3. 3.3. 配置Struts2+Spring+Mybatis3
    4. 3.4. 配置Log4j
    5. 3.5. 配置 ApplicationContext
    6. 3.6. 配置Struts2
    7. 3.7. 配置web.xml文件
    8. 3.8. 配置 tomcat 启动
  4. 4. 测试启动
    1. 4.1. 编写UserService
    2. 4.2. 编写UserAction
    3. 4.3. strtus action插件
  5. 5. 最后

前言

在 Intellij 中配置 SSM Web 开发框架。

  • Struts2 主要用它的视图统筹
  • Spring 整个框架的统筹
  • Mybatis3 持久层,MyBatis 是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架

参考:夕下奕林:Idea SpringMVC+Spring+MyBatis+Maven整合

项目创建

创建新的Maven WebApp项目

打开Intellij 选择File->New->Project...
然后在弹出对话框里依次选择:
左侧的Maven,顶部的Create from archetype和右侧的org.apache.maven.archetypes:maven-archetype-webapp
选择maven项目

点击Next,输入GroupIdArtifaceId
输入 GroupId 与 ArtifaceId

点击Next,这里主要是 Maven的环境配置,使用默认
Maven 默认环境

点击Next,输入工程名称(Project Name),修改保存目录(Project Location)
保存工程

注意: 如果选择的工程不存在,Intellij会提示自动创建该目录。
创建目录提示

配置项目目录

此时Intellij会进行初始化,Maven 会下载依赖基本项。
初始化完成后,项目结构差不多是这个样子:
inited project

src->main目录下创建几个文件夹
creat folders
打开 Intellij 底部标签栏的Terminal,并输入以下代码来批量创建目录:

1
2
3
4
5
mkdir -p src/test/java src/test/resources
cd src/main
mkdir -p java/com/lulee007/ssm/pojo java/com/lulee007/ssm/mapper java/com/lulee007/ssm/service java/com/lulee007/ssm/action
mkdir -p resources/config/mybatis resources/config/spring resources/config/struts2 resources/com/lulee007/ssm/mapper
mkdir webapp/WEB-INF/views

main目录下的java目录上右击,选择Mark Direcotry As->Sources Root
然后在test目录下的java目录上右击,选择Mark Direcotry As->Test Sources Root
最后在test目录下的resources目录上右击,选择Mark Direcotry As->Test Resources Root

配置项目

配置数据库连接mysql_db.properties

先配置数据库连接,方便接下来的Mybatis Generator和Spring配置中使用,
main/resources/config目录下创建文件mysql_db.properties输入下面的代码:

1
2
3
4
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=UTF-8
jdbc.username = root
jdbc.password =

配置Mybatis Generator

使用mybatis-generator-maven-plugin插件来自动生成 model 和 mapper 文件
参考: Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

  1. 准备数据库User 表,结构如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    DROP TABLE IF EXISTS `user`;
    /*!40101 SET @saved_cs_client = @@character_set_client */;
    /*!40101 SET character_set_client = utf8 */;
    CREATE TABLE `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(32) NOT NULL COMMENT '用户名称',
    `birthday` date DEFAULT NULL COMMENT '生日',
    `sex` char(1) DEFAULT NULL COMMENT '性别',
    `address` varchar(256) DEFAULT NULL COMMENT '地址',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
  2. 添加插件到pom.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <build>
    <finalName>ssm_demo</finalName>
    <!-- 以下是新增内容-->
    <plugins>
    <plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.2</version>
    <configuration>
    <verbose>true</verbose>
    <overwrite>true</overwrite>
    </configuration>
    </plugin>
    </plugins>
    </build>
  3. 配置generatorConfig.xml文件
    src/main/resouces目录下创建文件generatorConfig.xml,输入下面的内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <generatorConfiguration>
    <!-- 配置连接数据库的jar -->
    <classPathEntry location="F:\jar\mysql\mysql-connector-java-5.1.7-bin.jar"/>
    <context id="testTables" targetRuntime="MyBatis3" >
    <commentGenerator>
    <!-- 是否去除自动生成的注释 true:是 : false:否 -->
    <property name="suppressAllComments" value="false" />
    </commentGenerator>
    <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
    <!--<jdbcConnection driverClass="${jdbc.driver}"-->
    <!--connectionURL="${jdbc.url}"-->
    <!--userId="${jdbc.username}"-->
    <!--password="${jdbc.password}">-->
    <!--</jdbcConnection>-->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
    connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=UTF-8"
    userId="root"
    password="">
    </jdbcConnection>
    <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
    NUMERIC 类型解析为java.math.BigDecimal -->
    <javaTypeResolver>
    <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    <!-- targetProject:生成PO类的位置 -->
    <javaModelGenerator targetPackage="com.lulee007.ssm.pojo"
    targetProject="src\main\java">
    <!-- enableSubPackages:是否让schema作为包的后缀 -->
    <property name="enableSubPackages" value="false" />
    <!-- 从数据库返回的值被清理前后的空格 -->
    <property name="trimStrings" value="true" />
    </javaModelGenerator>
    <!-- targetProject:mapper映射文件生成的位置 -->
    <sqlMapGenerator targetPackage="com.lulee007.ssm.mapper"
    targetProject="src\main\resources">
    <!-- enableSubPackages:是否让schema作为包的后缀 -->
    <property name="enableSubPackages" value="false" />
    </sqlMapGenerator>
    <!-- targetPackage:mapper接口生成的位置 -->
    <javaClientGenerator type="XMLMAPPER"
    targetPackage="com.lulee007.ssm.mapper"
    targetProject="src\main\java">
    <!-- enableSubPackages:是否让schema作为包的后缀 -->
    <property name="enableSubPackages" value="false" />
    </javaClientGenerator>
    <!-- 指定数据库表 -->
    <table tableName="user"></table>
    <!-- 有些表的字段需要指定java类型
    <table schema="" tableName="">
    <columnOverride column="" javaType="" />
    </table> -->
    </context>
    </generatorConfiguration>
  4. 运行mybatis-generator-maven插件
    在 Intellij 右边侧边栏选择Maven Projects,选择Webapp下的Plugins->mybatis-generator
    展开后,双击即可运行此插件。
    run mybatis-generator
    最后输出结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building ssm_demo Maven Webapp 1.0-SNAPSHOT
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- mybatis-generator-maven-plugin:1.3.2:generate (default-cli) @ ssm_demo ---
    [INFO] Connecting to the Database
    [INFO] Introspecting table user
    log4j:WARN No appenders could be found for logger (org.mybatis.generator.internal.db.DatabaseIntrospector).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    [INFO] Generating Example class for table user
    [INFO] Generating Record class for table user
    [INFO] Generating Mapper Interface for table user
    [INFO] Generating SQL Map for table user
    [INFO] Saving file UserMapper.xml
    [INFO] Saving file UserExample.java
    [INFO] Saving file User.java
    [INFO] Saving file UserMapper.java
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1.402s
    [INFO] Finished at: Tue Jan 19 21:56:51 CST 2016
    [INFO] Final Memory: 5M/123M
    [INFO] ------------------------------------------------------------------------

build success 后应该会自动生成mapper接口文件、xml文件、pojo文件。
generated file

配置Struts2+Spring+Mybatis3

pom.xmldependencies节点中添加依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 与Struts2集成必须使用 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Struts2 依赖 -->
<!-- Struts2的核心包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- Struts2和Spring整合插件 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- Struts2 转json插件 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- struts2-config-browser-plugin used in dev mode -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.1</version>
</dependency>
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<!--mysql driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--c3p0数据库-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>

配置Log4j

  1. main/resources目录下新建log4j.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration threshold="trace">
    <appender name="stdout-appender" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %c{1}: %m%n" />
    </layout>
    </appender>
    <appender name="sql-appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="db_sql.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern"
    value="-----&gt; %d{yyyy-MM-dd HH:mm:ss.SSS} &lt;%t&gt; %m%n%n" />
    </layout>
    </appender>
    <appender name="sql-timing-appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="db_sqltiming.log"/>
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="-----&gt; %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n%n" />
    </layout>
    </appender>
    <appender name="jdbc-appender" class="org.apache.log4j.FileAppender">
    <param name="File" value="db_jdbc.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n" />
    </layout>
    </appender>
    <appender name="jdbc-connection" class="org.apache.log4j.FileAppender">
    <param name="File" value="db_connection.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n" />
    </layout>
    </appender>
    <appender name="web-file" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="web.log" /><!-- 设置日志输出文件名 -->
    <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
    <param name="Append" value="true" />
    <param name="MaxBackupIndex" value="30" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss}- [ %p ] %l %m%n" />
    </layout>
    </appender>
    <!-- spring -->
    <logger name="org.springframework" additivity="true">
    <level value="debug" />
    </logger>
    <!-- xwork -->
    <logger name="com.opensymphony" additivity="true">
    <level value="debug" />
    </logger>
    <logger name="org.apache.struts2" additivity="true">
    <level value="debug" />
    </logger>
    <logger name="freemarker.log.Log4JLoggerFactory" additivity="true">
    <level value="debug" />
    </logger>
    <!-- The Following 5 logs can be turned on and off while the server is running
    LIVE in order to trace the SQL and/or all JDBC coming out of the application.
    To turn a log on, set the level value to INFO or DEBUG (to see class name
    and line number information in the log) The DEBUG setting is much more inefficient
    but the output is much more useful. To turn off JDBC logging completely,
    you must set all 5 logs to a level higher than ERROR (FATAL is suggested.) -->
    <!-- log SQL (pre-execution) plus exceptions caused by SQL -->
    <logger name="jdbc.sqlonly" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <!-- log SQL with timing information, post execution -->
    <logger name="jdbc.sqltiming" additivity="true">
    <level value="debug" />
    <appender-ref ref="sql-timing-appender" />
    </logger>
    <!-- only use the two logs below to trace ALL JDBC information, NOTE: This
    can be very voluminous! -->
    <!-- log all jdbc calls except ResultSet calls -->
    <logger name="jdbc.audit" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <!-- log the jdbc ResultSet calls -->
    <logger name="jdbc.resultset" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <!-- log connection open/close events and dump of all open connection numbers -->
    <logger name="jdbc.connection" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <!-- this log is for internal debugging of log4jdbc, itself -->
    <!-- debug logging for log4jdbc itself -->
    <logger name="log4jdbc.debug" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <!-- by default, log everything to the console with a level of WARN or higher -->
    <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制-->
    <logger name="org.apache.activemq.transport.AbstractInactivityMonitor" additivity="false">
    <level value ="error"/>
    <appender-ref ref="stdout-appender" />
    </logger>
    <logger name="com.mchange.v2.resourcepool.BasicResourcePool" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <logger name="com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <logger name="com.mchange.v2.c3p0.impl.NewPooledConnection" additivity="false">
    <level value="error" />
    <appender-ref ref="stdout-appender" />
    </logger>
    <root>
    <level value="debug" />
    <appender-ref ref="stdout-appender" />
    <appender-ref ref="web-file" />
    </root>
    </log4j:configuration>
  2. 并拷贝log4j.dtd

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    <?xml version="1.0" encoding="UTF-8" ?>
    <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements. See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License. You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    -->
    <!-- Authors: Chris Taylor, Ceki Gulcu. -->
    <!-- Version: 1.2 -->
    <!-- A configuration element consists of optional renderer
    elements,appender elements, categories and an optional root
    element. -->
    <!ELEMENT log4j:configuration (renderer*, appender*,plugin*, (category|logger)*,root?,
    (categoryFactory|loggerFactory)?)>
    <!-- The "threshold" attribute takes a level value below which -->
    <!-- all logging statements are disabled. -->
    <!-- Setting the "debug" enable the printing of internal log4j logging -->
    <!-- statements. -->
    <!-- By default, debug attribute is "null", meaning that we not do touch -->
    <!-- internal log4j logging settings. The "null" value for the threshold -->
    <!-- attribute can be misleading. The threshold field of a repository -->
    <!-- cannot be set to null. The "null" value for the threshold attribute -->
    <!-- simply means don't touch the threshold field, the threshold field -->
    <!-- keeps its old value. -->
    <!ATTLIST log4j:configuration
    xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
    threshold (all|trace|debug|info|warn|error|fatal|off|null) "null"
    debug (true|false|null) "null"
    reset (true|false) "false"
    >
    <!-- renderer elements allow the user to customize the conversion of -->
    <!-- message objects to String. -->
    <!ELEMENT renderer EMPTY>
    <!ATTLIST renderer
    renderedClass CDATA #REQUIRED
    renderingClass CDATA #REQUIRED
    >
    <!-- Appenders must have a name and a class. -->
    <!-- Appenders may contain an error handler, a layout, optional parameters -->
    <!-- and filters. They may also reference (or include) other appenders. -->
    <!ELEMENT appender (errorHandler?, param*,
    rollingPolicy?, triggeringPolicy?, connectionSource?,
    layout?, filter*, appender-ref*)>
    <!ATTLIST appender
    name CDATA #REQUIRED
    class CDATA #REQUIRED
    >
    <!ELEMENT layout (param*)>
    <!ATTLIST layout
    class CDATA #REQUIRED
    >
    <!ELEMENT filter (param*)>
    <!ATTLIST filter
    class CDATA #REQUIRED
    >
    <!-- ErrorHandlers can be of any class. They can admit any number of -->
    <!-- parameters. -->
    <!ELEMENT errorHandler (param*, root-ref?, logger-ref*, appender-ref?)>
    <!ATTLIST errorHandler
    class CDATA #REQUIRED
    >
    <!ELEMENT root-ref EMPTY>
    <!ELEMENT logger-ref EMPTY>
    <!ATTLIST logger-ref
    ref CDATA #REQUIRED
    >
    <!ELEMENT param EMPTY>
    <!ATTLIST param
    name CDATA #REQUIRED
    value CDATA #REQUIRED
    >
    <!-- The priority class is org.apache.log4j.Level by default -->
    <!ELEMENT priority (param*)>
    <!ATTLIST priority
    class CDATA #IMPLIED
    value CDATA #REQUIRED
    >
    <!-- The level class is org.apache.log4j.Level by default -->
    <!ELEMENT level (param*)>
    <!ATTLIST level
    class CDATA #IMPLIED
    value CDATA #REQUIRED
    >
    <!-- If no level element is specified, then the configurator MUST not -->
    <!-- touch the level of the named category. -->
    <!ELEMENT category (param*,(priority|level)?,appender-ref*)>
    <!ATTLIST category
    class CDATA #IMPLIED
    name CDATA #REQUIRED
    additivity (true|false) "true"
    >
    <!-- If no level element is specified, then the configurator MUST not -->
    <!-- touch the level of the named logger. -->
    <!ELEMENT logger (level?,appender-ref*)>
    <!ATTLIST logger
    name CDATA #REQUIRED
    additivity (true|false) "true"
    >
    <!ELEMENT categoryFactory (param*)>
    <!ATTLIST categoryFactory
    class CDATA #REQUIRED>
    <!ELEMENT loggerFactory (param*)>
    <!ATTLIST loggerFactory
    class CDATA #REQUIRED>
    <!ELEMENT appender-ref EMPTY>
    <!ATTLIST appender-ref
    ref CDATA #REQUIRED
    >
    <!-- plugins must have a name and class and can have optional parameters -->
    <!ELEMENT plugin (param*, connectionSource?)>
    <!ATTLIST plugin
    name CDATA #REQUIRED
    class CDATA #REQUIRED
    >
    <!ELEMENT connectionSource (dataSource?, param*)>
    <!ATTLIST connectionSource
    class CDATA #REQUIRED
    >
    <!ELEMENT dataSource (param*)>
    <!ATTLIST dataSource
    class CDATA #REQUIRED
    >
    <!ELEMENT triggeringPolicy ((param|filter)*)>
    <!ATTLIST triggeringPolicy
    name CDATA #IMPLIED
    class CDATA #REQUIRED
    >
    <!ELEMENT rollingPolicy (param*)>
    <!ATTLIST rollingPolicy
    name CDATA #IMPLIED
    class CDATA #REQUIRED
    >
    <!-- If no priority element is specified, then the configurator MUST not -->
    <!-- touch the priority of root. -->
    <!-- The root category always exists and cannot be subclassed. -->
    <!ELEMENT root (param*, (priority|level)?, appender-ref*)>
    <!-- ==================================================================== -->
    <!-- A logging event -->
    <!-- ==================================================================== -->
    <!ELEMENT log4j:eventSet (log4j:event*)>
    <!ATTLIST log4j:eventSet
    xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
    version (1.1|1.2) "1.2"
    includesLocationInfo (true|false) "true"
    >
    <!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?,
    log4j:locationInfo?, log4j:properties?) >
    <!-- The timestamp format is application dependent. -->
    <!ATTLIST log4j:event
    logger CDATA #REQUIRED
    level CDATA #REQUIRED
    thread CDATA #REQUIRED
    timestamp CDATA #REQUIRED
    time CDATA #IMPLIED
    >
    <!ELEMENT log4j:message (#PCDATA)>
    <!ELEMENT log4j:NDC (#PCDATA)>
    <!ELEMENT log4j:throwable (#PCDATA)>
    <!ELEMENT log4j:locationInfo EMPTY>
    <!ATTLIST log4j:locationInfo
    class CDATA #REQUIRED
    method CDATA #REQUIRED
    file CDATA #REQUIRED
    line CDATA #REQUIRED
    >
    <!ELEMENT log4j:properties (log4j:data*)>
    <!ELEMENT log4j:data EMPTY>
    <!ATTLIST log4j:data
    name CDATA #REQUIRED
    value CDATA #REQUIRED
    >

配置 ApplicationContext

配置 Spring IOC 注入和事件控制,在main/resources/config/spring 中分别创建applicationContext-dao.xmlapplicationContext-service.xmlapplicationContext-transaction.xml文件。

  • applicationContext-dao.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--获取数据库配置文件-->
    <context:property-placeholder location="classpath:mysql_db.properties"/>
    <!--设置数据源c3p0-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="maxPoolSize" value="50"/>
    <property name="minPoolSize" value="2"/>
    <property name="maxIdleTime" value="60"/>
    </bean>
    <!--sqlsessionFactory bean-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="classpath:config/mybatis/SqlMapConfig.xml"/>
    <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--自动扫描mapper接口,并注入sqlsession-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.lulee007.ssm.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSession"/>
    </bean>
    </beans>
  • applicationContext-service.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--扫描service-->
    <context:component-scan base-package="com.lulee007.ssm.service"/>
    </beans>
  • applicationContext-transaction.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
    <tx:attributes>
    <tx:method name="find*" propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="add*" propagation="REQUIRED"/>
    </tx:attributes>
    </tx:advice>
    </beans>

配置Struts2

src/main/resources/config/struts2目录下添加struts-core.xml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 加载STRUTS默认配置 -->
<include file="struts-default.xml"/>
<include file="struts-plugin.xml"/>
<!-- 声明STRUTS常量配置 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<!-- struts.devMode used in dev mode -->
<constant name="struts.devMode" value="true"/>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.objectFactory"
value="org.apache.struts2.spring.StrutsSpringObjectFactory"/>
<!-- <constant name="struts.multipart.saveDir" value="/temp"/> -->
<constant name="struts.ui.theme" value="simple"/>
<!-- <constant name="struts.action.extension" value=","/>-->
<!-- <constant name="struts.multipart.saveDir" value="d:uploadtemp"/>-->
<!-- 改变struts2默认为2M的上传文件大小限制 -->
<constant name="struts.multipart.maxSize" value="1024000000"/>
<!-- 指定不经过struts2框架处理的URL规则-->
<!-- <constant name="struts.action.excludePattern" value="/downloadFile,/httpService,/dwr/.*,/dwr/test/.*"/> -->
<!-- 加载JSON结果转换,加载自定义结果 -->
<package name="my-struts" extends="struts-default" namespace="/">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult">
<!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
<!-- 指定是否序列化空的属性 -->
<param name="defaultEncoding">utf-8</param>
<param name="excludeNullProperties">false</param>
<!-- 指定内容类型,默认为application/json,IE浏览器会提示下载 -->
<param name="contentType">text/html</param>
<!-- 是否启用压缩 -->
<param name="enableGZIP">false</param>
<!-- 是否忽略层级关系,即不关注父类中的对象 -->
<param name="ignoreHierarchy">false</param>
<!-- 排除的对象 -->
<param name="excludeProperties">
request,session
</param>
</result-type>
</result-types>
<interceptors>
<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>
<!-- comment added by lulee007 设置找不到action默认跳转的页面->首页 index -->
<default-action-ref name="index"/>
<global-results>
<result name="json" type="json"/>
<result name="index" type="redirect">/index</result>
<result name="exception">/views/common/error.jsp</result>
</global-results>
</package>
<!-- 预留加载业务-Action配置 -->
<!--<include file="config/struts2/struts-user.xml"/>-->
</struts>

配置web.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- 设置log4j -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:config/log4j/log4j.xml</param-value>
</context-param>
<!--设置spring 配置文件的位置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/spring/applicationContext-*.xml</param-value>
</context-param>
<!--配置spring listener-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!--解决POST乱码问题-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Struts2的核心过滤器配置 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>config/struts2/struts-core.xml</param-value>
</init-param>
</filter>
<!-- Struts2过滤器拦截所有的.action请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

配置 tomcat 启动

点击 Intellij 顶部工具栏的Run/Debug Configurations...,选择Edit Configurations...
edit configurations
在弹出来的配置对话框中,点击左上角的+选择添加Tomcat Server->Local来添加一个本地的Tomcat Server
add tomcat server
然后配置 tomcat server:
填写顶部的Name,输入我们的工程名称ssm_demo,然后会在底部有个小灯泡提示,No artifacts for deployment,我们点击Fix
会有两个选择,我们选择第二个ssm_demo war:exploded,然后在Deployment标签页,填写Application context,输入/ssm_demo,这样当启动tomcat后,打开浏览器输入『localhost://8080/ssm_demo』就可以看到我们的主页了。
setting tomcat
注意: 如果在启动过程中提示端口号被占,可以通过修改这个configHttp port
set http port

测试启动

目前配置好了基本的项目,现在来测试一下:
点击 Intellij 顶部工具栏的Run/Debug Configurations...,这个时候应该有默认我们配置好的ssm_demo可以启动了。
点击 旁边的 Run(三角形),或者按快捷键Command+R来运行。
这时,Intellij 应该会自动弹出默认浏览器并打开主页http://localhost:8082/ssm_demo/,手动输入此地址也可以看到以下内容:
home page

编写UserService

编写Service来去数据库的用户信息:
新建UserService.java接口文件到src/main/java/com/lulee007/ssm/service/目录下,输入下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.lulee007.ssm.service;
import com.lulee007.ssm.pojo.User;
import java.util.List;
/**
* Created by lulee007 on 16/1/19.
*/
public interface UserService {
/**
* 查找所有用户
* @return
* @throws Exception
*/
List<User> findUser()throws Exception;
Boolean saveUser(User user) throws Exception;
}

然后新建userServiceImpl.java接口文件到src/main/java/com/lulee007/ssm/service/目录下,输入下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.lulee007.ssm.service;
import com.lulee007.ssm.mapper.UserMapper;
import com.lulee007.ssm.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by lulee007 on 16/1/19.
*/
// 注解为spring service
@Service
public class UserServiceImpl implements UserService {
//User接口
@Autowired
private UserMapper userMapper;
public List<User> findUser() throws Exception {
//调用mapper类中的selectByExample方法,如果传入类型为null,则表示无条件查找
List<User> users = userMapper.selectByExample(null);
return users;
}
public Boolean saveUser(User user) throws Exception {
return userMapper.insertSelective(user)==1;
}
}

编写UserAction

接下来测试一下 Struts2 ,我们用之前mybatis 帮我们生成好的 pojo,dao,mapper 来写一个展示user 信息的表格:

  • 新建UserAction.javasrc/main/java/com/lulee007/ssm/action/目录下,输入下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    package com.lulee007.ssm.action;
    import com.lulee007.ssm.pojo.User;
    import com.lulee007.ssm.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import java.util.Date;
    import java.util.List;
    /**
    * Created by lulee007 on 16/1/21.
    */
    //将这个UserAction 注解为Controller
    @Controller
    public class UserAction {
    //自动注解UserService
    @Autowired
    private UserService userService;
    private String title;
    private List<User> users;
    //action 默认执行的入口
    public String execute(){
    try {
    //取出所有user
    users=userService.findUser();
    } catch (Exception e) {
    e.printStackTrace();
    }
    //设置标题
    title="My User Page"+new Date();
    return "success";
    }
    /***
    * 以下是 getter setter 在jsp里要调用我们的 title 和 users 就必须写setter getter方法,不然
    * 没法取到或设置其值.
    * ****/
    /**
    *
    * @return
    */
    public String getTitle() {
    return title;
    }
    public void setTitle(String title) {
    this.title = title;
    }
    public List<User> getUsers() {
    return users;
    }
    public void setUsers(List<User> users) {
    this.users = users;
    }
    }
  • 创建action-user.xml
    创建action-user.xml文件到src/main/resources/config/struts2/目录下,输入下面的内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd">
    <struts>
    <package name="home" extends="my-struts" namespace="/user">
    <!-- User 列表页 -->
    <action name="index" class="com.lulee007.ssm.action.UserAction">
    <!--action 返回值为success时,则返回页面user.jsp,并解析为html展示到网页-->
    <result name="success">/WEB-INF/views/user.jsp</result>
    </action>
    </package>
    </struts>
  • 修改之前我们创建的src/main/resources/config/struts2/struts-core.xml
    把最后面,取消注释,最终如下:

    1
    2
    <!-- 加载业务-Action配置 -->
    <include file="config/struts2/struts-user.xml"/>
  • 添加user.jsp文件到src/main/webapp/WEB-INF/views/目录下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <%--
    Created by IntelliJ IDEA.
    User: lulee007
    Date: 16/1/21
    Time: 21:39
    To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="s" uri="/struts-tags" %>
    <html>
    <head>
    <title>${title}</title>
    </head>
    <body>
    <%--显示我们的设置的标题--%>
    <h1>${title}</h1>
    <%--显示我们从数据库取出来的用户数据--%>
    <table>
    <thead>
    <tr>
    <td>
    Name
    </td>
    <td>
    Birthday
    </td>
    <td>
    Sex
    </td>
    <td>
    Address
    </td>
    </tr>
    </thead>
    <tbody>
    <%--struts2的遍历标签,循环取出用户的信息--%>
    <s:iterator value="users" id="user">
    <tr>
    <td>${user.username}</td>
    <td>${user.birthday}</td>
    <td>${user.sex}</td>
    <td>${user.address}</td>
    </tr>
    </s:iterator>
    </tbody>
    </table>
    </body>
    </html>

重新运行 tomcat ,然后在地址栏里输入:http://localhost:8082/ssm_demo/user/index
可以看到页面:
user page

strtus action插件

Config Browser插件是一个可以在运行时查看应用配置的简单工具. 在调试一些和配置相关的问题时, 非常有用.
功能

Browsable view of loaded configuration 浏览已加载的配置
Shows all accessible action URLs 查看所有可以访问的URL

直接在浏览器输入YOUR_HOST+config-browser/index.action即可,如http://localhost:8082/ssm_demo/config-browser/index.action
confit-browser-1
这个是我们的UserAction相关的信息:
confit-browser-user-action

最后

至此我们完成了所有配置,本文主要介绍了最基本的用法,如果需要其他功能在这个基础上进行扩展即可。
项目源码:https://github.com/lulee007/ssm_demo tag:basic-ssm

本文总阅读量