|
|
|
# 传统web开发
|
|
|
|
|
|
|
|
SOP既可以作为网关服务开发,又可以作为传统的webapp服务开发,传统web开发意思是像普通的web开发那样提供restful接口,没有签名校验功能。
|
|
|
|
|
|
|
|
本篇介绍如何使用SOP进行传统web服务开发,即对接前端应用(H5、小程序、App)。
|
|
|
|
|
|
|
|
- 网关ZuulConfig继承WebappZuulConfiguration类
|
|
|
|
|
|
|
|
```java
|
|
|
|
@Configuration
|
|
|
|
public class ZuulConfig extends WebappZuulConfiguration {
|
|
|
|
|
|
|
|
static {
|
|
|
|
new ManagerInitializer();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
设置完毕,网关不在进行签名验证,网关统一的返回结果如下:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"result": {
|
|
|
|
...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
- 微服务OpenServiceConfig继承WebappServiceConfiguration类
|
|
|
|
|
|
|
|
```java
|
|
|
|
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的封装如下:
|
|
|
|
|
|
|
|
```js
|
|
|
|
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版本如下:
|
|
|
|
|
|
|
|
```js
|
|
|
|
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/api' // 网关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调用示例:
|
|
|
|
|
|
|
|
```js
|
|
|
|
$(function () {
|
|
|
|
var data = {
|
|
|
|
id: 1
|
|
|
|
,name: '葫芦娃'
|
|
|
|
}
|
|
|
|
RequestUtil.post('http://localhost:8081/rest/food/getFoodById', data, function (result) {
|
|
|
|
console.log(result)
|
|
|
|
});
|
|
|
|
})
|
|
|
|
```
|