|
|
@ -1,5 +1,7 @@ |
|
|
|
# 传统web开发 |
|
|
|
# 传统web开发 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SOP既可以作为网关服务开发,又可以作为传统的webapp服务开发,传统web开发意思是像普通的web开发那样提供restful接口,没有签名校验功能。 |
|
|
|
|
|
|
|
|
|
|
|
本篇介绍如何使用SOP进行传统web服务开发,即对接前端应用(H5、小程序、App)。 |
|
|
|
本篇介绍如何使用SOP进行传统web服务开发,即对接前端应用(H5、小程序、App)。 |
|
|
|
|
|
|
|
|
|
|
|
- 网关ZuulConfig继承WebappZuulConfiguration类 |
|
|
|
- 网关ZuulConfig继承WebappZuulConfiguration类 |
|
|
@ -35,6 +37,51 @@ public class OpenServiceConfig extends WebappServiceConfiguration { |
|
|
|
|
|
|
|
|
|
|
|
其它内容不变 |
|
|
|
其它内容不变 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 前端app请求网关 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
请求格式为:`http://ip:port/rest/your_path`,其中`http://ip:port/rest/`为固定部分,后面跟微服务请求路径。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
注意:为了确保各个微服务路径不冲突,必须保证类上方定义的`@RequestMapping`内容唯一,不与其它微服务重复。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
下面是一个微服务的接口例子 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
|
|
|
@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的封装如下: |
|
|
|
封装请求,方便调用,针对vue的封装如下: |
|
|
@ -46,24 +93,20 @@ import axios from 'axios' |
|
|
|
const client = axios.create({ |
|
|
|
const client = axios.create({ |
|
|
|
baseURL: process.env.BASE_API, // api 的 base_url |
|
|
|
baseURL: process.env.BASE_API, // api 的 base_url |
|
|
|
timeout: 5000, // 请求超时时间 |
|
|
|
timeout: 5000, // 请求超时时间 |
|
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } |
|
|
|
headers: { 'Content-Type': 'application/json' } |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const RequestUtil = { |
|
|
|
const RequestUtil = { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 请求接口 |
|
|
|
* 请求接口 |
|
|
|
* @param method 接口名,如:goods.get,goods.get |
|
|
|
* @param url 请求路径,如http://localhost:8081/rest/food/getFoodById |
|
|
|
* @param version 版本号,如:1.0 |
|
|
|
|
|
|
|
* @param data 请求数据,json格式 |
|
|
|
* @param data 请求数据,json格式 |
|
|
|
* @param callback 成功回调 |
|
|
|
* @param callback 成功回调 |
|
|
|
* @param errorCallback 失败回调 |
|
|
|
* @param errorCallback 失败回调 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
post: function(method, version, data, callback, errorCallback) { |
|
|
|
post: function(url, data, callback, errorCallback) { |
|
|
|
client.post(''/* 这里不用填 */, { |
|
|
|
client.post(url, data) |
|
|
|
method: method, |
|
|
|
.then(function(response) { |
|
|
|
version: version, |
|
|
|
|
|
|
|
biz_content: JSON.stringify(data) |
|
|
|
|
|
|
|
}).then(function(response) { |
|
|
|
|
|
|
|
const resp = response.result |
|
|
|
const resp = response.result |
|
|
|
const code = resp.code |
|
|
|
const code = resp.code |
|
|
|
// 成功,网关正常且业务正常 |
|
|
|
// 成功,网关正常且业务正常 |
|
|
@ -94,23 +137,18 @@ jQuery版本如下: |
|
|
|
var RequestUtil = { |
|
|
|
var RequestUtil = { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 请求接口 |
|
|
|
* 请求接口 |
|
|
|
* @param method 接口名,如:goods.get,goods.get |
|
|
|
* @param url 请求路径,如http://localhost:8081/rest/food/getFoodById |
|
|
|
* @param version 版本号,如:1.0 |
|
|
|
|
|
|
|
* @param data 请求数据,json格式 |
|
|
|
* @param data 请求数据,json格式 |
|
|
|
* @param callback 成功回调 |
|
|
|
* @param callback 成功回调 |
|
|
|
* @param errorCallback 失败回调 |
|
|
|
* @param errorCallback 失败回调 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
post: function(method, version, data, callback, errorCallback) { |
|
|
|
post: function(url, data, callback, errorCallback) { |
|
|
|
$.ajax({ |
|
|
|
$.ajax({ |
|
|
|
url: 'http://localhost:8081/api' // 网关url |
|
|
|
url: 'http://localhost:8081/api' // 网关url |
|
|
|
, type: 'post' |
|
|
|
, type: 'post' |
|
|
|
, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } |
|
|
|
, headers: { 'Content-Type': 'application/json' } |
|
|
|
, data: { |
|
|
|
, data: data |
|
|
|
method: method, |
|
|
|
,success:function(response) { |
|
|
|
version: version, |
|
|
|
|
|
|
|
biz_content: JSON.stringify(data) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
,success:function(response){ |
|
|
|
|
|
|
|
var resp = response.result |
|
|
|
var resp = response.result |
|
|
|
var code = resp.code |
|
|
|
var code = resp.code |
|
|
|
// 成功,网关正常且业务正常 |
|
|
|
// 成功,网关正常且业务正常 |
|
|
@ -137,13 +175,8 @@ $(function () { |
|
|
|
id: 1 |
|
|
|
id: 1 |
|
|
|
,name: '葫芦娃' |
|
|
|
,name: '葫芦娃' |
|
|
|
} |
|
|
|
} |
|
|
|
RequestUtil.post('alipay.story.get', '1.0', data, function (result) { |
|
|
|
RequestUtil.post('http://localhost:8081/rest/food/getFoodById', data, function (result) { |
|
|
|
console.log(result) |
|
|
|
console.log(result) |
|
|
|
}); |
|
|
|
}); |
|
|
|
}) |
|
|
|
}) |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
1.7.1开始支持接口名版本号放在url后面,规则:`http://host:port/{method}/{version}/`(最后的`/`不能少),如:`http://localhost:8081/story.demo.get/1.0/` |
|
|
|
|
|
|
|
等同于:`http://localhost:8081/api?method=story.demo.get&version=1.0`。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
把接口名版本号放在url后面的好处是调用接口一目了然,在浏览器F12调试的时候特别有用,可以一眼看到调用了哪些接口,否则将会看到全部都是api请求,需要点开查看request header才能知道到底调用了哪个接口 |
|
|
|
|
|
|
|