SSM整合,快速新建javaWeb项目

整合前需要了解:

spring和springmvc包扫描的注意事项

Spring applicationContext.xml (父容器),SpringMVC springmvc-servlet.xml (子容器)

此时项目中有两个工厂

  • DispatcherServlet 启动的springMVC工厂==负责生产C及springMVC自己的系统组件(Servlet)

  • ContextLoaderListener 启动的spring工厂==负责生产其他所有组件(Listener)

  • springMVC的工厂会被设置为spring工厂的子工厂,可以随意获取spring工厂中的组件

  • 整合过程,就是累加:代码+依赖+配置。然后将service注入给controller即可

两个工厂不能有彼此侵入,即,生产的组件不能有重合。

  • mvc.xml中只扫描controller包, 其他不管, 其他包交给spring框架
    <!-- 告知SpringMVC  哪些包中 存在 被注解的类
        use-default-filters=true 凡是被 @Controller @Service  @Repository注解的类,都会被扫描
        use-default-filters=false 默认不扫描包内的任何类, 只扫描include-filter中指定的类
        只扫描被@Controller注解的类
    -->
    <context:component-scan base-package="com.xx" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

     

  • applicationContext.xml中不扫描controller包, 这个包交给springMvc框架, spring框架扫描非controller的其他包
    <!-- 告知Spring
         唯独不扫描@Controller注解的类 -->
    <context:component-scan base-package="com.xx" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

 

正式开始整合

一、准备测试用的数据库

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `gender` tinyint(255) DEFAULT NULL,
  `regist_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', '青龙', '123', '1', '2021-03-07 09:08:39');
INSERT INTO `t_user` VALUES ('2', '白虎', '123', '0', '2021-03-01 09:08:56');
INSERT INTO `t_user` VALUES ('3', '朱雀', '123', '0', '2021-03-01 09:09:10');
INSERT INTO `t_user` VALUES ('4', '玄武', '123', '1', '2021-03-07 09:09:24');

 

二、创建项目, 项目名为ssmDemo, 选择骨架为 maven-archetype-webapp, 创建后pom文件内容如下:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
    <!-- springMVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>

    <dependency>
        <!-- jstl 支持 -->
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <!-- servlet编译环境 -->
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <!-- jsp编译环境 -->
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- FastJson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.54</version>
    </dependency>

    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.6.RELEASE</version>
    </dependency>

    <!-- Spring整合mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.1</version>
    </dependency>

    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>

    <!-- mysql驱动 依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
        <scope>runtime</scope>
    </dependency>

    <!-- 连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.12</version>
    </dependency>

    <!-- Junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>

    <!-- 分页插件 -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.10</version>
    </dependency>
</dependencies>

 

三、检查或创建项目结构

  • main目录下新建java目录放java源代码

    • java目录下创建包com.xx.controller 放控制层代码

    • java目录下创建包com.xx.dao 放持久层代码

    • java目录下创建包com.xx.service放业务层代码

    • java目录下创建包com.xx.pojo放实体类代码

    • java目录下创建包com.xx.utils 放工具类代码

    • java目录下创建包com.xx.config放初始化类代码

    • java目录下创建包com.xx.interceptor放拦截器代码

  • main目录下创建resources目录放配置文件

    • resources目录下创建com/xx/dao用于放置mybatis中对应的dao映射文件

  • webapp/WEB-INF/目录下创建 jsp目录放页面

  • webapp目录下创建js目录, img目录, css目录用于放置, js脚本, 图片, css样式

 

 

web.xml配置:

<?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_4_0.xsd"
         version="4.0">

  <!-- SpringMVC前端(核心)控制器
       1. 前端,接收所有请求
       2. 启动SpringMVC工厂  mvc.xml
       3. springMVC流程调度
  -->
  <servlet>
      <servlet-name>mvc_shine</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:mvc.xml</param-value>
      </init-param>
      <!-- 懒 饿  可选-->
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>mvc_shine</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); -->
  <filter>
      <filter-name>encoding</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>encoding</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 启动Spring工厂 -->
  <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>
</web-app>
applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- DataSource -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--基本配置-->
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="${jdbc.init}"/>
        <property name="minIdle" value="${jdbc.minIdle}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>

        <!-- 配置获取连接等待超时的时间 ms-->
        <property name="maxWait" value="60000"/>

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
    </bean>

    <!-- SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 注入dao-mapper文件信息 ,如果映射文件和dao接口 同包且同名,则此配置可省略-->
        <property name="mapperLocations">
            <list>
                <value>classpath:com/xx/dao/*.xml</value>
            </list>
        </property>
        <!-- 为 dao-mapper文件中的实体 定义缺省包路径
            如:<select id="queryAll" resultType="User"> 中 User类可以不定义包
        -->
        <property name="typeAliasesPackage" value="com.xx.pojo"></property>

        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <!-- 页号 调整到合理的值  0  max -->
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <!-- DAO  MapperScannerConfigurer -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- dao接口所在的包  如果有多个包,可以用逗号或分号分隔
           <property name="basePackage" value="com.a.dao,com.b.dao"></property>
        -->
        <property name="basePackage" value="com.xx.dao"></property>
        <!-- 如果工厂中只有一个SqlSessionFactory的bean,此配置可省略 -->
        <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>-->
    </bean>

    <!-- 扫描包,并排除Controller -->
    <context:component-scan base-package="com.xx" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 引入一个事务管理器,其中依赖DataSource,借以获得连接,进而控制事务逻辑 -->
    <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- @Transactional -->
    <tx:annotation-driven transaction-manager="tx"/>
</beans>

mvc.xml配置

<beans     xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          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
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 注解扫描 -->
    <context:component-scan base-package="com.xx" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </context:component-scan>

    <!-- 注解驱动 -->
    <mvc:annotation-driven>
        <!-- 安装FastJson,转换器 -->
        <mvc:message-converters>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <!-- 声明转换类型:json -->
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 视图解析器
         作用:1.捕获后端控制器的返回值="hello"
              2.解析: 在返回值的前后 拼接 ==> "/hello.jsp"
     -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--
       额外的增加一个handler,且其requestMapping:  "/**" 可以匹配所有请求,但是优先级最低
      所以如果其他所有的handler都匹配不上,请求会转向 "/**" ,恰好,这个handler就是处理静态资源的
      处理方式:将请求转会到tomcat中名为default的Servlet

      RequestMapping  /*   /a   /b  /c   /dxxxx    /a/b
                      /**
     -->
    <mvc:default-servlet-handler/>
</beans>

jdbc.properties配置

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb2?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.init=1
jdbc.minIdle=1
jdbc.maxActive=3

---测试用的页面---

/WEB-INF/jsp/ 目录下页面user.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html lang="en">
<head>
    <title>Hello, world!</title>
</head>
<body>

    <table width="500px" align="center" border="1px">
        <thead>
            <tr>
                <th>id</th>
                <th>username</th>
                <th>password</th>
                <th>gender</th>
                <th>registTime</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${requestScope.users}" var="user">
                <tr>
                    <td>${user.id}</td>
                    <td>${user.username}</td>
                    <td>${user.password}</td>
                    <td>${user.gender}</td>
                    <td>
                        <fmt:formatDate value="${user.registTime}" pattern="yyyy-MM-dd"/>
                    </td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
</body>
</html>

/WEB-INF/jsp/ 目录下页面userPro.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!doctype html>
<html lang="en">
<head>
    <title>Hello, world!</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1ixxktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

</head>
<body>

    <table class="table table-bordered table-striped table-dark">
        <thead>
            <tr>
                <th>id</th>
                <th>username</th>
                <th>password</th>
                <th>gender</th>
                <th>registTime</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${requestScope.data.list}" var="user">
                <tr>
                    <td>${user.id}</td>
                    <td>${user.username}</td>
                    <td>${user.password}</td>
                    <td>${user.gender}</td>
                    <td>
                        <fmt:formatDate value="${user.registTime}" pattern="yyyy-MM-dd"/>
                    </td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <nav aria-label="...">
        <ul class="pagination justify-content-center" >
            <c:if test="${requestScope.data.hasPreviousPage}">
                <li class="page-item">
                    <a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${requestScope.data.prePage}" tabindex="-1" aria-disabled="true">Previous</a>
                </li>
            </c:if>
            <c:if test="${!requestScope.data.hasPreviousPage}">
                <li class="page-item disabled">
                    <a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${requestScope.data.prePage}" tabindex="-1" aria-disabled="true">Previous</a>
                </li>
            </c:if>

            <%--<li class="page-item"><a class="page-link" href="#">1</a></li>
            <li class="page-item active" aria-current="page">
                <a class="page-link" href="#">2 <span class="sr-only">(current)</span></a>
            </li>
            <li class="page-item"><a class="page-link" href="#">3</a></li>--%>

            <c:forEach begin="1" end="${requestScope.data.pages}" var="pageNum">
                <c:if test="${pageNum==requestScope.data.pageNum}">
                    <li class="page-item active"><a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${pageNum}">${pageNum}</a></li>
                </c:if>
                <c:if test="${pageNum!=requestScope.data.pageNum}">
                    <li class="page-item"><a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${pageNum}">${pageNum}</a></li>
                </c:if>
            </c:forEach>


                <c:if test="${requestScope.data.hasNextPage}">
                    <li class="page-item">
                        <a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${requestScope.data.nextPage}">Next</a>
                    </li>
                </c:if>
                <c:if test="${!requestScope.data.hasNextPage}">
                    <li class="page-item disabled">
                        <a class="page-link" href="${pageContext.request.contextPath}/users?pageNum=${requestScope.data.nextPage}">Next</a>
                    </li>
                </c:if>

        </ul>
    </nav>
</body>
</html>

 

准备实体类pojo

package com.xx.pojo;

import java.util.Date;

public class User {
    private Integer id;
    private String username;
    private String password;
    private Boolean gender;
    private Date registTime;

    public User(){}
    public User(Integer id, String username, String password, Boolean gender, Date registTime) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.gender = gender;
        this.registTime = registTime;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", gender=" + gender +
                ", registTime=" + registTime +
                '}';
    }

    //  ....... get 和 set 方法......
  
}
package com.xx.pojo;

public class Page {
    private Integer pageNum;
    private Integer pageSize=3;

    public Page(){}

    public Page(Integer pageNum, Integer pageSize) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
    }

    @Override
    public String toString() {
        return "Page{" +
                "pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                '}';
    }

    //  ....... get 和 set 方法......

}

dao接口

package com.xx.dao;

import com.xx.pojo.User;

import java.util.List;

public interface UserDao {
    
    List<User> queryUsers();
}

dao映射文件

dao映射文件放在resources/com/xx/dao目录下必须叫做 UserDao.xml

<?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="com.xx.dao.UserDao">

    <select id="queryUsers" resultType="User">
        select id,username,password,gender,regist_time registTime
        from t_user
    </select>
</mapper>

service接口

public interface UserService {
    PageInfo<User> queryUsers(Page page);
}

service实现类

@Service // userServiceImpl
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDAO;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public PageInfo<User> queryUsers(Page page) {
        PageHelper.startPage(page.getPageNum(),page.getPageSize());
        List<User> users = userDAO.queryUsers();
        return new PageInfo<User>(users);
    }
}

controller类

@Controller
public class UserController {

    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userService;

    @GetMapping("/users")
    public String queryUsers(Model model, Page page){
        System.out.println("queryUsers");
        PageInfo<User> pageInfo = userService.queryUsers(page);
        model.addAttribute("data",pageInfo);
        return "userPro";
    }

    @RequestMapping("/users/{id}")
    public String queryOne(@PathVariable Integer id){
        System.out.println("query user id:"+id);
        return "index";
    }

    @PostMapping(value = "/users")
    public String updateUser(User user){
        System.out.println("update User:"+user);
        return "index";
    }
}

测试整合结果

启动tomcat, 访问地址如下:

http://localhost:8081/users?pageNum=1

 

posted @ 2021-11-26 12:06  何足道66  阅读(137)  评论(0)    收藏  举报