zoukankan      html  css  js  c++  java
  • 微服务迁移记(五):WEB层搭建(1)

    WEB层是最终表现层,注册至注册中心,引用接口层(不需要引用实现层)、公共服务层。用户登录使用SpringSecurity,Session保存在redis中,权限管理没有用SpringSecurity那套,自己写了一个简单的菜单、按钮权限控制。我在虚拟机192.168.0.7中搭了一个redis服务。

    一、redis搭建

    下载redis后,在linux下启动比较简单。需要注意的是redis.config配置:

    1. 如果想配置用户名密码

     requirepass 123456

    2. 如果不bind IP地址,默认只能本机访问

    bind 192.168.0.7

    写一个批处理startredis.sh,启动redis

    ./redis-5.0.7/src/redis-server ./redis-5.0.7/redis.conf

    二、WEB层主要依赖包

     <!--依赖系统管理相关接口工程,供Feign调用,减少冗余代码-->
            <dependency>
                <groupId>com.zyproject</groupId>
                <artifactId>zyproject-api-service-system</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    <!-- 公共类工程-->
            <dependency>
                <groupId>com.zyproject</groupId>
                <artifactId>zyproject-common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    <!-- redis,需要注意的是引入commons-pool2,否则会报错 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
                <version>2.2.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    <!--引入feign,远程调用Service服务-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>2.2.1.RELEASE</version>
            </dependency>
            <!--整合freemarker-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
            <!--依赖系统管理相关接口工程-->
            <dependency>
                <groupId>com.zyproject</groupId>
                <artifactId>zyproject-api-service-system</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!--spring secrity-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-oauth2</artifactId>
                <version>2.1.4.RELEASE</version>
            </dependency>

    三、FeignClient通用接口

    创建一个接口,继承自接口层ISystemService,这样就可以直接使用Feign实现RPC调用接口实现层暴露出来的http服务了。

    package com.zyproject.web.feignclient;
    
    import com.zyproject.service.ISystemService;
    import org.springframework.cloud.openfeign.FeignClient;
    
    /**
     * @program: zyproject
     * @description: RPC调用系统管理相关接口服务
     * @author: zhouyu(zhouyu629 # qq.com)
     * @create: 2020-02-11
     **/
    @FeignClient("zyproject-api-service-system") //注意这里,对应的是接口实现层在注册中心的别名。我这个别名取的有点问题,跟接口层不一样,不合适。
    public interface SystemFeign extends ISystemService {
    
    }

    然后建立一个Service包,里面调用这个Feign接口,最后Controller调用Service即可。以UserService为例:

    package com.zyproject.web.service;
    
    import com.zyproject.common.ResponseData;
    import com.zyproject.web.feignclient.SystemFeign;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.bind.annotation.RequestParam;
    
    /**
     * @program: zyproject
     * @description: 用户服务
     * @author: zhouyu(zhouyu629 # qq.com)
     * @create: 2020-02-11
     **/
    @Service
    public class UserService {
        @Autowired
        private SystemFeign systemFeign;
    
        //用户登录
        public ResponseData userLogin(@RequestParam String user_code, @RequestParam String password){
            return systemFeign.userLogin(user_code,password);
        }
    
        //根据登录名,获取用户信息
        public ResponseData findByLoginname(String login_name){
            return systemFeign.findByLoginname(login_name);
        }
    }

    有个细节需要注意:

    Feign直接调用接口实现RPC,这使得远程调用简单了很多,传递参数可以是一些Java类型,比如传Entity、List、Map等对象。最终底层应该是HttpClient,默认会报错,但可以解决。

    但从实际应用角度出发,不建议这样做,向外暴露的http接口,理论上也可以提供给其他应用程序使用,其他开发语言调用,不能限制死是java类型,建议是通过gson或fastjson,将这些类型转换为json字符串进行http参数传递,实现侧再转换回java类型。下面是一个例子:

    客户端请求:

     /**
         * 设置角色权限
         * @param role_id
         * @param tree_ids:考虑到对其他语言的兼容性,不建议传java类型
         * @param btn_ids:考虑到对其他语言的兼容性,不建议传java类型
         * @return
         */
        public ResponseData setRoleRight(@RequestParam int role_id,
                                         @RequestParam(name = "tree_ids",required = true) String  tree_ids,
                                         @RequestParam(name = "btn_ids",required = true) String btn_ids){
            return systemFeign.setRoleRight(role_id,tree_ids,btn_ids);
        }
    
        /**
         * 新增或编辑角色
         * @param roleEntity:角色信息,Feign前转换为json字符串
         * @return
         */
        public ResponseData addOrUpdateRole(RoleEntity roleEntity){
            String role = new Gson().toJson(roleEntity);
            return this.systemFeign.addOrUpdateRole(role);
        }

    服务端接收(类型转换,应该做容错判断,代码里没有做):

     @PostMapping("/setRoleRight")
        @ApiOperation("设置角色权限")
        @ApiImplicitParams({
                @ApiImplicitParam(name = "role_id",value = "角色ID",dataType = "int"),
                @ApiImplicitParam(name = "tree_ids", value = "选中的菜单",dataType = "String"),
                @ApiImplicitParam(name = "btni_ds",value = "选中的按钮",dataType = "String")
        })
        @Override
        @Transactional
        public ResponseData setRoleRight(int role_id, String tree_ids,String btn_ids) {
            Gson gson = new Gson();
            List<String> tree = gson.fromJson(tree_ids,new TypeToken<List<String>>(){}.getType());
            List<Map<String,String>> btn = gson.fromJson(btn_ids,new TypeToken<List<Map<String,String>>>(){}.getType());
            boolean result = this.roleDao.setRoleRight(role_id,tree,btn);
            return ResponseData.out(result?CodeEnum.SUCCESS:CodeEnum.FAIL,null);
        }
    
        @GetMapping("/addOrUpdateRole")
        @ApiOperation("新增或修改角色")
        @ApiImplicitParams(
                @ApiImplicitParam(name = "role",value = "角色实体json字符串")
        )
        @Override
        public ResponseData addOrUpdateRole(String role) {
            //将role转换为实体类
            boolean result = this.roleDao.addOrUpdateRole(new Gson().fromJson(role,RoleEntity.class));
            return ResponseData.out(result?CodeEnum.SUCCESS:CodeEnum.FAIL,null);
        }

    四、SpringSecurity集成

    待续

    五、FreeMarker集成

    待续

    六、权限管理

    待续

  • 相关阅读:
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之六 多点触控
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之九 定位
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之七 重力感应
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之五 保存数据的几种方式
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之八 照相机
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之三 Application 配置详解
    Adobe Flash Builder 4.5 Android Air 程序开发系列 之四 打开与关闭应用程序是的保存数据
    ADOBE FLASH BUILDER 4.6 IOS 开发之部署与调试
    [译] 高性能JavaScript 1至5章总结
    页签及盒子的web标准实现
  • 原文地址:https://www.cnblogs.com/zhouyu629/p/12340961.html
Copyright © 2011-2022 走看看