You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
SOP/doc/docs/files/10100_传统web开发.md

5.1 KiB

传统web开发

SOP既可以作为网关服务开发,又可以作为传统的webapp服务开发,传统web开发意思是像普通的web开发那样提供restful接口,没有签名校验功能。

本篇介绍如何使用SOP进行传统web服务开发,即对接前端应用(H5、小程序、App)。

  • 网关ZuulConfig继承WebappZuulConfiguration类
@Configuration
public class ZuulConfig extends WebappZuulConfiguration {

    static {
        new ManagerInitializer();
    }

}

设置完毕,网关不在进行签名验证,网关统一的返回结果如下:

{
	"result": {
		...
	}
}
  • 微服务OpenServiceConfig继承WebappServiceConfiguration类
public class OpenServiceConfig extends WebappServiceConfiguration {
    ...
}

其它内容不变

  • 前端app请求网关

请求格式为:http://ip:port/rest/your_path,其中http://ip:port/rest/为固定部分,后面跟微服务请求路径。

注意:为了确保各个微服务路径不冲突,必须保证类上方定义的@RequestMapping内容唯一,不与其它微服务重复。

下面是一个微服务的接口例子

@RestController
@RequestMapping("food")
public class TraditionalWebappController {
    @ApiMapping(value = "getFoodById", method = RequestMethod.GET)
    public Food getFoodById(Integer id) {
        Food food = new Food();
        food.setId(id);
        food.setName("香蕉");
        food.setPrice(new BigDecimal(20.00));
        return food;
    }
    
    // 加版本号
    @ApiMapping(value = "getFoodById", method = RequestMethod.GET, version = "1.1")
        public Food getFoodById2(Integer id) {
            Food food = new Food();
            food.setId(id);
            food.setName("香蕉2");
            food.setPrice(new BigDecimal(22.00));
            return food;
        }
}

这是一个食品服务例子,假设网关ip为10.0.1.11,端口8081;食品服务ip为10.0.1.22,端口2222

  1. 网关访问:http://10.0.1.11:8081/rest/food/getFoodById?id=2。加版本号:http://localhost:8081/rest/food/getFoodById?id=2&version=1.1

  2. 本地访问:http://10.0.1.22:2222/food/getFoodById/?id=2

更多例子,可查看源码类:TraditionalWebappController.java

由此可见,对于前端调用者来说,它把网关看做一个大服务,只访问网关提供的请求,不需要关心网关后面的路由转发。网关后面各个微服务独自管理, 微服务之间的调用可以使用dubbo或feign,有了版本号的管理,可以做到服务的平滑升级,对用户来说都是无感知的。结合SOP-Admin提供的上下线功能, 可实现预发布环境功能。

  • 封装请求工具【可选】

封装请求,方便调用,针对vue的封装如下:

import axios from 'axios'

// 创建axios实例
const client = axios.create({
  baseURL: process.env.BASE_API, // api 的 base_url
  timeout: 5000, // 请求超时时间
  headers: { 'Content-Type': 'application/json' }
})

const RequestUtil = {
  /**
   * 请求接口
   * @param url 请求路径,如http://localhost:8081/rest/food/getFoodById
   * @param data 请求数据,json格式
   * @param callback 成功回调
   * @param errorCallback 失败回调
   */
  post: function(url, data, callback, errorCallback) {
    client.post(url, data)
        .then(function(response) {
        const resp = response.result
        const code = resp.code
        // 成功,网关正常且业务正常
        if (code === '10000' && !resp.sub_code) {
          callback(resp)
        } else {
          // 报错
          Message({
            message: resp.msg,
            type: 'error',
            duration: 5 * 1000
          })
        }
      })
      .catch(function(error) {
        console.log('err' + error) // for debug
        errorCallback && errorCallback(error)
      })
  }
}

export default RequestUtil

jQuery版本如下:

var RequestUtil = {
    /**
     * 请求接口
     * @param url 请求路径,如http://localhost:8081/rest/food/getFoodById
     * @param data 请求数据,json格式
     * @param callback 成功回调
     * @param errorCallback 失败回调
     */
    post: function(url, data, callback, errorCallback) {
        $.ajax({
            url: 'http://localhost:8081' // 网关url
            , type: 'post'
            , headers: { 'Content-Type': 'application/json' }
            , data: data
            ,success:function(response) {
                var resp = response.result
                var code = resp.code
                // 成功,网关正常且业务正常
                if (code === '10000' && !resp.sub_code) {
                    callback(resp)
                } else {
                    // 报错
                    alert(resp.msg);
                }
            }
            , error: function(error) {
                errorCallback && errorCallback(error)
            }
        });
    }
}

jQuery调用示例:

$(function () {
    var data = {
        id: 1
        ,name: '葫芦娃'
    }
    RequestUtil.post('http://localhost:8081/rest/food/getFoodById', data, function (result) {
        console.log(result)
    });
})