SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码

Spring

       Spring是最受欢迎的企业级java应用程序开发框架,Spring最被人所认同的技术是控制反转的依赖注入(DI)模式。控制反转(Ioc)是一个通用的概念,它可以用许多种不同的方式去表达,而依赖注入仅仅是控制反转的一个具体的例子。除此之外Spring广为人知一个框架便是AOP,关于AOP的应用有很多不错的例子,如日志记录、声明性事务、安全性、和缓存等等。关于Spring的控制反转(Ioc)以及控制反转的依赖注入模式(DI)与Spring的关键组件面向方面的程序设计(AOP)框架这里就不做过多的阐述,有兴趣的小伙伴可以去看我关于Spring的专题。

SpringMVC

        SpringMVC框架是一个基于请求的驱动的web框架,并且使用了前端控制器的模型来进行设计,再根据映射规则分发给相应的页面控制器进行处理。

        整体流程如下:

         1.首先用户发送请求到前端控制器(DispatcherServlet),前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它。图中的1、2步骤。

         2.页面控制器收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理,处理完毕后返回一个ModelAndView(模型数据和逻辑图名),图中的3、4、5步骤。

         3.前端控制器收回控制权,然后根据返回的逻辑视图名选择相应的视图进行渲染,并把模型数据传入以便视图渲染。图中的6、7步骤。

         4.前端控制器再次收回控制权,将响应返回给用户,至此请求过程中后端请求过程结束,图中的8步骤。

         SpringMVC请求过程核心流程:

具体步骤:

第一步:发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求处理器映射器(HandlerMapping)查找处理器(Handler)。注:可以根据xml配置、注解进行查找

第三步:处理器映射器(handlerMapping)向前端控制器返回处理器(Handler),HandlerMapping会把请求映射为HandlerExcutionChain对象(它包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略。

第四步:前端控制器调用处理器适配器去执行Handler

第五步:处理器适配器(HandlerAdapter)将会根据适配的结果去执行Handler

第六步:Handler执行完成给适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView(ModelAndView是SpringMvc框架的一个底层对象,包括Model和View)

第八步:前端控制器请求视图解析器去进行视图解析(根据逻辑视图名解析成真诚的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可。

第九步:视图解析器向前端控制器返回View

第十步:前端控制器进行视图渲染(视图渲染将模型数据(在ModelAndVies)填充到request域)

第十一步:前端控制器向用户响应结果。

 

核心开发步骤:

1.DispatcherServlet在web.xml中描述,从而拦截请求到Spring Web Mvc

2.HandlerMapping的配置,从而将请求映射到处理器

3.HandlerAdapter的配置,从而支持多种类型的处理器

注:处理器映射器和处理器适配器包含在注解驱动中,不需要再单独配置。

4.ViewResolver的配置,从而将逻辑视图名解析为具体视图技术

5.处理器(页面控制器)的配置,从而进行功能处理

View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)

Mybatis

      mybatis的前身是Apache的开源项目iBatis。mybatis几乎可以代替JDBC,是一个支持普通SQl查询、存储过程和高级映射的基于java的优秀持久层框架。mybatis与JDBC相比,减少了50%以上的代码量。并且满足高并发和高响应的要求,所以它称为最流行的java互联网持久框架。

      mybatis使用简单的XML或注解用于配置和原始映射,将接口和java的POJOs(Plain Old Java Objects,普通的java对象)映射成数据库中的记录  。关于mybatis的后续将会有相应的mybatis专栏,有兴趣的朋友可以前去指正一下。

SSM整合思路

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第1张图片

在Spring中将各层进行整合

通过Spring管理持久层的mapper(相当于dao接口)

通过Spring管理业务层的service,service中可以调用mapper接口。

在Spring中进行事务控制

通过Spring管理表现层Controller,Controller中可以调用service接口。

mapper、service、Controller都是javabean,可以由Spring来进行统一管理。

基本思路:

第一步:整合dao

mybatis和spring整合,通过spring管理mapper接口。

使用mapper的扫描器自动扫描mapper接口在spring中进行注册。

第二步:整合service

通过Spring管理service接口。

使用配置方式将service接口配置在spring配置文件中。

实现事务控制。

第三步:整合springmvc

由于springmvc是spring的模块,不需要整合。

SSM整合

ssm使用图解

进行ssm三大框架整合之前先大概了解一下三大框架各自的作用,在整合思路里已经说过了,这里重新赘述一下,加深一下理解

1.SpringMVC:他用于web层,相当于Controller(等价于传统的servlet和struts的action),用来处理用户请求。举个例子用户在地址栏输入http://网站域名/login,那么springmvc就会拦截到这个请求,并且调用controller层中相应的方法(中间可能包含验证用户名密码和业务和逻辑,以及查询数据库操作,但这些都不是springmvc的职责),最终把结果返回给用户,并且返回相应的页面(当然也可以只返回json/xml等格式数据)。springmvc就是做前面和后面的活,与用户打交道。

2.Spring:关于spring与我们平常开发接触最多的就是IOC容器,他可以装载bean(也就是我们java中的类,当然也包括service      和dao里面的),有了这个机制我们就不用在每次使用这个类的时候为它初始化,很少看到关键字new。另外Spring的aop,事务管理等我们也是十分经常遇到。

3.MyBatis:如果你想问它跟那个大名鼎鼎的Hibernate有什么区别,我只能说mybatis更符合大多数人的需求。第一、他能自由控制sql,这会让有数据库经验的人编写的代码能够提高数据库访问的效率。第二、他可以使用xml的方式来组织管理sql,因为一般程序出错很多情况下是sql出错,别人接手代码后能够快速找到出错的地方,甚至可以优化原来写的sql。

第一步:创建maven工程

1.创建项目

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第2张图片

2.选择maven——>Create from archetype——>选择如图模版

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第3张图片

3.命名

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第4张图片

这里着重说一下,GroupId是项目组织的唯一标识符,举个例子,如果你的公司名字叫做myself,有个项目叫做study,那么GroupId就应该是com.myself.study;而ArtifactedId则定义了当前项目在组中唯一的ID,比如study-ssm、study-shiro、study-redis等等。

填好了GroupId和ArtifactedId以后一直next,初次创建的时候生成比较慢,耐心等待就好了。生成项目如下:

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第5张图片

第二步:创建目录

生成的项目只是很简单的项目结构,并不能满足我们的需求,所以我们要创建一些目录,如下:

SSM超详细整合教程(附带shiro+log4j2框架的整合)及源码_第6张图片

目录介绍如下:

文件名 作用
src 根目录,下面有main
main 主要目录,可以放java代码和一些资源文件。
java 存放 Java 代码
com java文件的子文件
myself com文件的子文件

equipment

区别于主程序的其他代码,如果没有,也可以不用创建
study 存放主要的java代码

controller

存放我们程序的接口代码也就是控制器,springmvc就是在这里发挥作用的
dao 数据访问层:与数据打交道,可以是数据库操作,也可以是文件读写操作,甚至是redis缓存操作,总之与数据操作有关的都放在这里,在这里我们只需要写接口就可以,不用实现dao接口的实现类impl,因为我们使用的持久层框架是mybatis,可以在mapper中的xml配置文件中直接实现接口的方法。
entity 实体类:一般来说与数据库的表相对应,封装dao层取出来的数据为对象,一般只在dao层与service层传输。
service 业务逻辑层:在此处一般来处理我们的业务逻辑,controller直接调用它,将控制器层与逻辑层分开,有利于解耦合。
resources 存放资源文件,如spring,springmvc,mybatis,日志、数据库等的配置文件。
conf 存放程序的配置文件,一般存放spring,mybatis,日志、数据库等
applicationContext.xml Spring的配置文件

generator.properties

mybatis中的代码自动生成功能的属性文件
generatorConfig.xml mybatis中的代码自动生成功能的配置文件
jdbc.properties 配置数据库的相关参数
log4j2.xml 配置日志的相关参数
springmvc.xml 配置springmvc的配置文件
mapper 存放dao中每个方法对应的sql,故而dao不需要写方法的实现(impl)
sql sql文件中一般存放一些sql的脚本,比如数据库的表或者其他方面的改动。
system system文件中可以放一些程序中用到的其他的properties文件,与conf中的properties文件区分开来,便于调用。
webapp 存放前端的静态资源,比如jsp,js,css等
resources 这里的resources存放项目的静态资源,比如js,css,image等
css 存放css
images 存放iamge
js 存放js文件
WEB-INF 很重要的一个目录,外部浏览器无法访问,只有项目内部才能访问,可以把jsp放在这里,另外就是web.xml了。你可能有疑问了,为什么上面java中的resources里面的配置文件不妨在这里,那么是不是会被外部窃取到?你想太多了,打包部署时候基本上只有webapp里面的静态资源如js、image、css等会直接输出到根目录,其他都会放入WEB-INF里面,项目内部依然可以使用classpath:XXX来访问,IDE里可以设置部署输出目录
jsp 存放jsp代码
web.xml 一个重要的但非必须配置文件,web.xml是用来配置欢迎页、servlet、filter等的,当你的web工程没用到这些的时候,你可以不用web.xml文件来配置你的web工程。
index.jsp jsp进入网站默认的首页,也可以通过web.xml的配置来更改首页的jsp
pom.xml pom.xml是maven的配置文件,pom.xml主要描述了项目的maven坐标、依赖关系、开发者需要遵从的规则、组织和licenses、以及其他所有你的项目相关因素。是项目级别的配置文件。

接下来就进行ssm的整合,在整合的过程中同时整合了log4j2与shiro框架;

第三步:配置相关配置文件

pom.xml:




    4.0.0

    com.myself.study
    study-ssm
    1.0-SNAPSHOT
    war

    study-ssm Maven Webapp
    
    http://www.example.com

    
        
        UTF-8
        UTF-8
        
        5.2.2.RELEASE
        4.2.3.RELEASE
        1.2
        4.0.1
    

    
        
        
            org.springframework
            spring-core
            ${spring.version}
        
        
            org.springframework
            spring-web
            ${spring.version}
        
        
            org.springframework
            spring-webmvc
            ${spring.version}
        

        
        
            jstl
            jstl
            ${jstl.version}
        
        
            javax.servlet
            javax.servlet-api
            4.0.1
            provided
        

        
        
        
            org.apache.logging.log4j
            log4j-slf4j-impl
            2.11.2
        
        
        
            org.apache.logging.log4j
            log4j-web
            2.11.2
        
        
        
            org.apache.logging.log4j
            log4j-jcl
            2.11.2
        

        
        
            com.alibaba
            fastjson
            1.2.62
        
        
        
            org.mybatis
            mybatis
            3.4.4
        
        
        
            org.mybatis
            mybatis-spring
            1.3.0
        
        
        
        
            org.springframework
            spring-jdbc
            5.2.2.RELEASE
        

        
        
            mysql
            mysql-connector-java
            5.1.41
        

        
        
        
            org.apache.shiro
            shiro-core
            1.5.2
        
        
        
            org.apache.shiro
            shiro-web
            1.5.2
        
        
        
            org.apache.shiro
            shiro-spring
            1.5.2
        

        
        
        
            org.projectlombok
            lombok
            1.18.10
            provided
        

        
        
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.10.1
        
        
        
            com.fasterxml.jackson.core
            jackson-core
            2.10.1
        
        
        
            com.fasterxml.jackson.core
            jackson-annotations
            2.10.1
        

    
    
        studyssm
        
            
                src/main/resources
                
                    **/*.xml
                    **/*.properties
                
            
        

        
        
    

applicationContext.xml




    
    
    


    
    
        
    


    
    
    
    
    
        
        
        
        
    

    
    
        
        
        
        
        
    

    
    
        
        
    

    
    
    
    
        
    
    
    
        
        
        
        
        
        
        
        
            
                
                /loginAdmin=anon
                
                /admin*=authc
                /student=roles[teacher]
                /teacher=perms["user:create"]
            
        
    
    
    
    
    
    
        
    

spring-mvc.xml




    
    
    
    
    
    
    
    
        
    
    

    
    
        
        
        
        
        
        
        
        
        
        
        
    
    
    
    

mybatis-config.xml


        

    
    
        
    


    



jdbc.properties

driver=com.mysql.jdbc.Driver
#mytest为我本地的数据库名
url=jdbc:mysql://localhost:3306/ssm?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
username=root
#下面输入自己数据库的密码
password=123456
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

log4j2.xml






    
        
        /Users/danghongen/temporary/log
        test.log
    
    
    
        
        
            
            
        
        
        
        
            
        
        
        
        
        
            
            
            
            
            
            
                
                
                
                
            
            
            
        

        
            
            
            
                
                
            
        
        
            
            
            
                
                
            
        
    
    
    
        
        
        
        
        
            
            
            
            
        
        
        
        
    

generator.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8
username=root
password=123456

#entity 包名和 java目录
modelPackage=com.myself.study.entity
modelProject=src/main/java
#sqlmap包名 和resources目录
sqlPackage=mapper
sqlProject=src/main/resources
#mapper包名和 java目录
mapperPackage=com.myself.study.dao
mapperProject=src/main/java

generatorConfig.xml




    
    

    
    
        
        
            
             
        

        
        
        
            
            
        

        
        
            
            
            
            
        
        
        
            
            
        
        
        
            
            
        

        
        

web.xml:




  studySSM

  
    shiroFilter
    org.springframework.web.filter.DelegatingFilterProxy
    
      
      targetFilterLifecycle
      true
    
  
  
    shiroFilter
    /*
  

  
    index.jsp
  
  
  
    log4jConfiguration
    
    classpath:conf/log4j2.xml
  
  
  
    org.apache.logging.log4j.web.Log4jServletContextListener
  
  

  
  
    contextConfigLocation
    classpath:conf/applicationContext.xml
  
  
    org.springframework.web.context.ContextLoaderListener
  

  
    org.springframework.web.util.IntrospectorCleanupListener
  



  
  
    springMvc
    org.springframework.web.servlet.DispatcherServlet
    
    
      contextConfigLocation
       classpath:conf/spring-mvc.xml
    
    1
  
  
  
    springMvc
    /
  

关于ssm与shiro整合主要是realm的重写,重写的realm名字为myRealm类,该类需要继承AuthorizingRealm并重写doGetAuthorizationInfo()方法与doGetAuthenticationInfo()方法;如下所示:

myRealm.java

package com.myself.study.service.realm;

import com.myself.study.entity.SysUser;
import com.myself.study.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;

public class myRealm extends AuthorizingRealm {

//  注解Resource与Autowired类似但不相同
    @Autowired
    UserService userService;

    /**
     * 为当前登录成功的用户授予权限和角色,已经登录成功了
     */

    /*参数解释:
    * PrincipalCollection:是一个身份集合,而方法getPrimaryPrincipal则是得到主要的身份,需要注意的是,如果只有一个Principal则直接返回,如果有多个,则返回第一个(因为内部使用map储存,所以可以认为是返回任意一个)
    * SimpleAuthorizationInfo:用于聚合授权信息
    * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username=(String) principalCollection.getPrimaryPrincipal();//获取用户名
        SimpleAuthorizationInfo authenticationInfo=new SimpleAuthorizationInfo();
        authenticationInfo.setRoles(userService.getRoles(username));//set角色字符串信息
        authenticationInfo.setStringPermissions(userService.getPermissions(username));//set权限字符串信息
        return authenticationInfo;
    }


    /**
     * 验证当前登陆的用户,获取认证信息
     */
    /*参数解释:
    * AuthenticationToken:AuthenticationToken 用于收集用户提交的身份(如用户名)及凭据(如密码)
    *AuthenticationInfo:AuthenticationInfo对象中存储的是主体(Subject)的身份认证信息。Shiro会调用CredentialsMatcher对象的doCredentialsMatch方法
                        对AuthenticationInfo对象和AuthenticationToken进行匹配。匹配成功则表示主体(Subject)认证成功,否则表示认证失败。。
 *在认证成功以后进行权限与角色的查询,需要创建SimpleAuthenticationInfo对象。
 * SimpleAuthenticationInfo:SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
userInfo, //用户名–此处传的是用户对象
userInfo.getPassword(), //密码—从数据库中获取的密码
salt,//盐–用于加密密码对比,–获取的经验:为了防止两用户的初始密码是一样的,
       四个参数,防止两用户可能初始密码相同时候用,token 用simplehash(四个参数的构造) 加密默认用了MD5 迭代一次加密,
       info中在密码比对调用new SimpleHash(String algorithmName, Object source)这个实例化对象默认迭代一次了,
       所以当你用三个参数加密时候可能两 个初始密码相同人的就没能区别开 (因此realm中密码要从数据库的查的原因),通过设置reaml 中credentialsMatcher 属性的各项属性可实现
getName() //当前的realm名
); */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String username=token.getUsername();//获取用户名
        String password= Arrays.toString(token.getPassword());
        SysUser user=userService.getByUsername(username);
        if (user!=null){
            if (!password.equals(user.getPassword())){
                return new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"myRealm");
            }else {
                throw new AccountException("密码错误!");
            }

        }else {
            throw new AccountException("账号不存在");
        }
    }
}

以上是我整合完成后的配置文件,在整合的过程中还遇到过很多问题,我专门写了一篇问题集锦,以及相应的源码地址以及数据库的sql文件!

文章地址如下:https://blog.csdn.net/weixin_40159122/article/details/105507947

源码地址如下(附带数据库的SQL文件):https://github.com/danghongen/study-ssm

想学习的童鞋一定要自己手动搭建一遍,遇到问题可以留言给我!

你可能感兴趣的:(SSM)