[手把手教程][JavaWeb]优雅的SpringMvc+Mybatis应用(八)

[手把手教程][JavaWeb]优雅的SpringMvc+Mybatis应用(八)

项目github地址:https://github.com/pc859107393/SpringMvcMybatis

我的首页是:http://www.jianshu.com/users/86b79c50cfb3/latest_articles

上一期是:优雅的SpringMvc+Mybatis应用(七)

工具

  • IDE为idea16
  • JDK环境为1.8
  • gradle构建,版本:2.14.1
  • Mysql版本为5.5.27
  • Tomcat版本为7.0.52
  • 流程图绘制(xmind)

本期目标

  • 多角色控制思路整理
  • 第一季项目总结

多角色控制思路整理

关于多角色控制,起始用户角色按照用户职能分工,一般来说思路如下:

  • 登陆成功根据用户角色,跳转不同的界面模块
  • 每个界面模块都有用户权限校验,防止用户逾越雷池一步
  • 后端接口需要做用户角色校验,用户异常调用接口,就中断用户访问。
  • 后端的web页面根据不同用户分组存放,然后各个用户之间不做关联

第一季项目总结

第一季的仓库管理系统到目前为止基本上算是结束了。虽然说不是完整的系统,但是我们在里面已经大概把基本的web开发的东西都梳理过了。我们现在来从头到尾的梳理一下吧。从我们项目从头到尾,我们分为几个阶段:

  • 项目基本框架选择
  • 项目框架整合、验证
  • 项目需求分析
  • 功能模块开发思路整理
  • Spring经典三层应用
  • 开发细节思考
  • web页面简单优化
  • js网络请求实现
  • ··· 等等

项目基本框架选择:

说实话这是一个技术活,我们程序员的角度来说无外乎就是实现容易、扩展便捷、运行稳定等等。按照软件工程的话来说就是节约成本、提高质量。

说点人话就是:从产品设计到编码,这一切基本都是人的活动,所以我们选择的框架首先要降低学习技术成本、开发技术成本、设计转换编码的成本、不同应用(模块)整合成本等等。

再总结一下:我们程序的编码语言应该是我们最熟悉的,应用的各个模块之间交互应该是我们擅长的。

所以我选择了java作为主要的编程语言,后端框架就是Spring+SpringMVC+Mybatis,后端数据库为Mysql。

项目框架整合、验证:

首先我们需要使用构建工具引入Spring+SpringMVC+Mybatis这些框架的jar包,方式有大概两种:①自行下载jar包②使用自动化构建工具完成下载。方式一中需要我们自行选择jar包手动下载然后引入到lib文件夹。方式二我们只需要使用类似代码的方式控制程序自动下载。先进的工具能提高生产力,所以我们选择自动化构建完成jar包引入。

第一步,引入jar包,我们在gradle中引入,代码如下:

   testCompile group: 'junit', name: 'junit', version: '4.11'
   compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.1'
   compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.6'
   compile group: 'com.alibaba', name: 'druid', version: '1.0.25'
   compile group: 'org.mybatis', name: 'mybatis', version: '3.4.1'
   compile group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.0'
   compile group: 'taglibs', name: 'standard', version: '1.1.2'
   compile group: 'jstl', name: 'jstl', version: '1.2'
   compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
   compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
   //Spring 框架基本的核心工具类
   compile group: 'org.springframework', name: 'spring-core', version: '4.3.2.RELEASE'
   //访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
   //如果应用只需基本的IoC/DI 支持,引入spring-core.jar 及spring-beans.jar 文件就可以了。
   compile group: 'org.springframework', name: 'spring-beans', version: '4.3.2.RELEASE'
   //Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。
   compile group: 'org.springframework', name: 'spring-context', version: '4.3.2.RELEASE'
   //Spring 对JDBC 数据访问进行封装的所有类。
   compile group: 'org.springframework', name: 'spring-jdbc', version: '4.3.2.RELEASE'
   //spring-tx 事务管理
   compile group: 'org.springframework', name: 'spring-tx', version: '4.3.2.RELEASE'
   //Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。
   //外部依赖spring-context, Servlet API, (JSP API, JSTL, Commons FileUpload, COS)。
   compile group: 'org.springframework', name: 'spring-web', version: '4.3.2.RELEASE'
   //Spring MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。
   compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.2.RELEASE'
   compile group: 'org.springframework', name: 'spring-test', version: '4.3.2.RELEASE'
   compile group: 'redis.clients', name: 'jedis', version: '2.7.3'
   //序列化和反序列化工具
   compile group: 'com.dyuproject.protostuff', name: 'protostuff-core', version: '1.0.8'
   compile group: 'com.dyuproject.protostuff', name: 'protostuff-runtime', version: '1.0.8'
   //文件上传工具类,不过可以使用Spring自带的文件工具
   compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
   compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.2'
   compile group: 'commons-io', name: 'commons-io', version: '2.5'
   //请求的UserAgent拆装箱工具
   compile group: 'eu.bitwalker', name: 'UserAgentUtils', version: '1.20'
   runtime group: 'mysql', name: 'mysql-connector-java', version: '5.1.37'

第二步,设置各个框架,并保存到配置文件中,我们的WebApp最重要的最基本的配置是web.xml,这里配置了我们基本程序的设定,同样的我们需要在这里导入一些设置,如下:



   
       index.html
       index.htm
       index.jsp
       default.html
       default.htm
       default.jsp
   
   
   
   
       SSM
       mvc-dispatcher
       org.springframework.web.servlet.DispatcherServlet
       
       
           contextConfigLocation
           classpath:spring/spring-*.xml
       
   
   
       mvc-dispatcher
       
       /
       
       
       
   

   
   
   
       encodingFilter
       org.springframework.web.filter.CharacterEncodingFilter
       
           encoding
           UTF-8
       
       
       
           forceEncoding
           true
       
   
   
       encodingFilter
       /*
   
   
   
   
       DruidStatView
       com.alibaba.druid.support.http.StatViewServlet
       
           
           loginUsername
           pc859107393
       
       
           
           loginPassword
           laopo5201314
       
   
   
       DruidStatView
       /druid/*
   
   
       druidWebStatFilter
       com.alibaba.druid.support.http.WebStatFilter
       
           exclusions
           /public/*,*.js,*.css,/druid*,*.jsp,*.swf
       
       
           principalSessionName
           sessionInfo
       
       
           profileEnable
           true
       
   
   
       druidWebStatFilter
       /*
   

   
       404
       /static/view/404.html
   

按照上面所说的,我们生成spring文件的存放路径后,我们接着应该做的是控制spring,那么spring的配置文件如下(很多时候我们可以看到他们有的只有一个配置文件,而我将它们拆分成为三个配置文件),具体实现如下:

  • spring-dao.xml配置文件


   
   
   
   

   
   
       
       
       
       
       

       
       
       
       

       
       

       
       

       
       

       

       
       
       

       
       
       

       

       

       
       
       
       
           
               
           
       
    
    
    
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
    

    
        
    

  • spring-service.xml配置文件

    
    
        
        
        
            
            
        
    
        
        
            
            
        
    
        
        
    
    
  • spring-web.xml配置文件

    
    
        
        
        
        
        
        
        
        
        
        
        
    
        
        
            
                
                
            
        
    
        
        
            
            
            
        
    
        
            
        
    
        
        
            
            
        
    
    
    

上面的Spring的配置文件我们完成后,我们需要把对应的其他文件配置好,如jdbc、mapper、mybatis等的配置文件,以及开发、测试的代码和资源文件的存放目录等等。这些在我们的第一期就能看到了,这里不再赘述。

关于项目框架验证,我们需要在搭建完成后,打开日志调试来看信息,有这几点原则:

  • 数据库链接正常
    • 数据库驱动、数据库服务
    • 数据库配置文件
    • 数据库测试
  • 网页资源访问正常
    • 静态html、js、css、font、image、MP3等
    • 动态的接口
    • 动态页面如:jsp
  • 提示信息正常
    • 异常输出
    • log输出
  • 等等···

具体的检测我们在第二期里面提到过,这里我们也就跳过吧,毕竟主角还在后面。

项目需求分析,本身来说也不是我们作为程序员应该考虑的,毕竟涉及到的东西很多,这里我么略过,我们在以后的开发中再提。

起始这里我最想说的额就是前面开发的细节,也就是我们当中用到的知识点。按照我们开发的思路来说,我们先从Dao层来实现,来一起看看前面用到的知识点。

首先我们需要一个基类的Dao接口,同时我们需要用泛型来解耦,告诉程序我们这里需要的什么样的对象来存入数据库,同时某些对象特有的方法那么就在该对象的自身的接口中实现。我们的基类Dao层如下:

/**
 * 通过接口编程
 *
 * @param  泛型用于解耦,同时避免写重复代码
 */
interface Dao {
    /**
     * 添加某个对象
     *
     * @param t 待添加的对象
     * @return 返回受影响的行数
     */
    int add(T t);

    /**
     * 删除某个对象,在企业开发中,我们一般不做物理删除,只是添加某个字段对其数据进行可用控制
     *
     * @param t 待删除对象
     * @return 返回受影响的条数
     */
    int del(T t);

    /**
     * 更新某个对象
     *
     * @param t 待更新对象
     * @return 返回受影响的条数
     */
    int update(T t);

    /**
     * 通过ID查找一个对象
     *
     * @param Id 待查询的对象的ID
     * @return 返回该ID对应的对象
     */
    T findOneById(Serializable Id);

    /**
     * 查找对象集合
     *
     * @return 返回对象集合
     */
    List findAll();
}

这里我们需要重点说一下多参数的Dao方法和返回List的Dao方法,话不多说,直接上代码:

//Dao层中,多参数的方法如何让Mybatis响应?
    /**
     * 分页查询
     * @param offset    起始位置
     * @param limit     每页数量
     * @return
     */
    List findAll(@Param("offset") int offset, @Param("limit") int limit);
//从上面我们可以看到,我们方法参数的前面都加上了注解@Param(),同时在注解中填写了对应的名字,这是为何?请看下面的Mybatis的xml中的内容:

    
//在上面的Mybatis的xml中的内容看来,我们是需要拿到上面参数对应的注解名字。
//同时,我在xml文件中的select语句的id为findAll也和Dao中的方法相对应,resultType返回数据类型设定为UserActionLog。
//通过这样简单的设定就可以实现列表查找了。

//我们接着看看下面的Dao层的代码:
int update(User user);

//上面的是在UserDao里复制出来的,它对应的mapper为UserDao.xml,对应的方法为:
    
    
        UPDATE
        `user`
        SET
        `name`=#{name}, `age`=#{age}, `sex`=#{sex}, `duty`=#{duty}, `cell_number`=#{cellNumber}, `photo_url`=#{photoUrl}
        WHERE
        `login_id`=#{loginId};
    
//注意我前面提到过mapper中的id必须和方法名一样的,“#{字段名}”这种格式表示:
//①如果接口的方法中传递的是对象,则表示该字段为对象的某一个属性
//②如果接口的方法中传递的是一个或者多个参数,则该字段对应为接口中参数的注解,如上面的findAll

Service层基本没啥好复习的,毕竟现在是直接调用Dao层。 Service层作为web应用的数据驱动层,我们需要在当中加入事务管理、考虑在Dao层中使用存储过程等设计来使我们程序执行更加高效。一般来说在java web中,我们后端开发长提的是面向接口编程,同理我们需要通过泛型解耦然后继承和实现BaseService接口。我们要使框架自动加载我们的Service我们需要做到以下几点:

  • 在Service的实现上面使用@Service("xxxService")注解
  • 在Dao层调用的地方打上注解@Autowired
  • 在controller里面调用Service这里同样需要在定义的地方注解@Autowired

起始我们应该重点强调下Controller层,毕竟我们web服务的动态资源都是从Controller层这里出来的,好的闲话不说,直接从代码走起:

@Controller //表明这个是Controller,只要这个类放在Spring配置文件指定的Controller路径中就能自动装载
@RequestMapping("/actionLog")   //域名后面跟的最外层地址
public class ActionLogController {
    @Autowired
    ActionLogService actionLogService;  //自动注入ActionLogService

    /**
     * 分页查找行为日志,其实druid里面已经包含了行为日志
     *
     * @param pageNum  页码
     * @param pageSize 每一页的条数
     * @return
     */
    @RequestMapping(value = "/findLogList"
            , produces = "application/json; charset=utf-8") //这里访问地址的形式是:http://xxx.cn/actionLog/findLogList,响应请求头的ContentType表明响应是json数据,字符编码为utf8
    @ResponseBody   //表明这个方法直接返回的是响应体的内容
    public Object findLog(int pageNum, int pageSize) {  
        //···代码省略
        return json数据;
    }
//关于请求的参数说明:
    //①当请求的解析方法中有基本数据类型的参数(无论个数)时候,mvc框架会自动把请求数据存储为名称相同的变量的值
        //比如说上面我们的访问为:http://域名/actionLog/findLogList?pageNum=10&pageSize=10
    //②当请求的解析方法中有封装数据类型的参数(无论个数)时候,mvc框架会自动根据请求数据的名字查找封装数据的对应字段并且自动存值,且无论该数据使用了几次。
        // 比如说我网页登陆的时候有两个用户体系,但是他们是通过用户名关联在一起的,那么如下:
        
        //请求为:http:acheng1314.cn/user/login?userId=acheng&pwd=123456
        
        //请求的解析方法是:
        @RequestMapping(value = "/login"
            , produces = "application/json; charset=utf-8")
        @ResponseBody   //表明这个方法直接返回的是响应体的内容
        public Object findLog(User user, Person person) {  
            //···代码省略
            System.out.printf("log:\t"+user.toString());
            System.out.printf("log:\t"+person.toString());
            return json数据;
        }
            //我们可以看到输出的日志为:
            User{"userId=acheng, pwd=123456, xxx=xxx···"}
            Person{"userId=acheng, pwd=123456, xxx=xxx···"}
        //所以当你后端接收这里无论你又多少实体,但是只要包含对应的字段,那么就会自动赋值。
}

在Controller里面我们要注意的是:

  • @RequestMapping 注解在类上
  • @RequestMapping 注解在方法上
  • 方法里的参数前面的@RequestParam注解
  • URI模板完成RESTful风格的站点和API → 下一季会详细介绍

关于web只有大概下面几点:

  • 减少每个页面的请求数。
  • js方法整合到页面,工具js封装成工具。
  • js方法一般写在页面头部
  • web页面除非整体刷新,其他情况考虑异步请求。
  • 页面图片资源整合到一起,然后根据位置取图片
  • web页面良好体验可以考虑组件引入
  • 页面需要大量重用的地方可以考虑模板完成

其实很多东西这个总结都没详细的说出来,毕竟开发细节的东西都不是三言两语说的明白的,但是完全不慌,即将开始第二季《完整的博客后端+Android客户端+分模块开发+七牛云存储+微信支付宝整合》正在蕴量,小伙伴们请鼓励我一下。

希望喜欢我的这个系列的读者,可以点击喜欢和收藏。谢谢。

本期项目包里面有福利,后端请求兼容Form表单提交、json数据post接收,请大家自行查找。拜拜,下期见。

你可能感兴趣的:([手把手教程][JavaWeb]优雅的SpringMvc+Mybatis应用(八))