文章目录
最近工作中居然遇到了项目搭建不符合常理的问题。更不符合高内聚低耦合的思想。总的感受就是一塌糊涂。借此建议各位朋友。做项目务必一定做好前期准备。系统的扩展性,接口复用性,模块依赖等问题一定考虑好。架构的搭建一定已项目需求为准,切记不可因时间等其他外在因素成为项目存在问题的借口!!
OK!进入正题!
前面我们主要介绍了nginx,redis技术的讲解。现在开始我们进入到前台。围绕订单,购物车,搜索等业务功能进行相关技术的讲解。
本节先讲解 单点登录(SSO) 的相关技术
1.前台项目的导入
从我的GitHub
上将jt-web中的静态页面档一下。这些页面是仿的京东做的。具体页面问题不需过多研究。我们只需研究它的接口访问即可.目录如下
2.js跨域
再讲单点登录之前,先来介绍一下js跨域的问题。
我们目前的系统架构为:
jt-common:公共api封装,以及POJO对象,redis配置,全局异常拦截配置,json转化工具类等共用接口
jt-manage:后台管理系统:包含基本ssm架构,以及缓存相应的aop工具类和后端页面,样式等信息
jt-web:前台系统。则是用户使用的系统。除了基本的ssm相关信息外。还有特殊的httpClient工具类。我们可以看到在后台其实已经封装了相关商品的增加,详情信息等接口方法。那前台没有必要再次编写相关业务方法,我们只需访问后台即可。而我们的后台也要对其作相应的处理并返回前台想要的信息即可。
jt-sso:单点登录系统。在这也许有朋友就会产生疑问,问啥登录专门作为一个登录系统进行开发呢。
说明一下:本教程的系统开发是站在百万级,千万级或亿万级的吞吐量的角度进行开发。跟京东或淘宝一样。那系统就要按照模块进行开发。达到低耦合高内聚的思想方式。登录,订单,购物车,付款等都要分离出来,并专门对访问吞吐量进行处理,减少系统的负荷。提高响应速度
此登录系统是专门处理注册,登录,多模板共享登录信息。那此方法涉及到的js问题就要访问前端了。这就涉及到了跨域问题。
2.1 同源策略
浏览器规定:进行ajax访问时必须满足同源策略的要求.
请求协议: //域名:端口号如果三项都相同则满足同源策略.浏览器可以实现数据的访问
2.2 跨域测试
现在jt-manage模块中测试js,调用的请求地址与域名相同
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//{"id":"1","name":"tom"}
$.get("http://manage.jt.com/test.json",function(data){
alert(data.name);
})
})
</script>
目录如下所示:
创建此案例需要的test.json文件
test.json
{"id":"1","name":"tom"}
当然朋友你可以自行放文件位置。只要能访问就可以
.
写一个请求路径映射方法:
@RequestMapping("/{name}")
public String test(@PathVariable String name) {
return "/"+name;
}
我们打开项目。确认是否打开nginx。这里用到了域名代理。我们访问一下
我们可以看到信息正常提示,这也符合同域的条件。
我们在jt-web模块访问,将test.html复制一份到jt-web模块中。运行看效果
可以看到 访问json数据可以成功获取.但是数据不能正确的解析.
2.3 跨域实现
根据同源策略,可以看到,在jt-web引入下列的js发现jQuery函数类库可以正常使用.说明了javaScript中的src属性浏览器不会限制.该策略称之为开放策略
能否利用javaScript中src属性实现跨域请求.
新建一个页面。testJS.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>
<script type="text/javascript">
/*JS是解释执行的语言 */
/*2定义回调函数 */
function hello(data){
alert(data.name);
}
//前端动态获取后端????
</script>
<!--1该json一直保存到浏览器中等待调用,但是没有函数名称无法调用 -->
<script type="text/javascript" src="http://manage.jt.com/test.json"></script>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
</head>
<body>
<h1>JS跨域问题</h1>
</body>
</html>
并将jt-manage下的test.json修改:
hello({"id":"1","name":"tom"})
访问一下:
跨域实现的底层原理
1. 利用javaScript中的src属性实现跨域的请求.
2. 定义回调函数 格式 function xxx(data)
3. 返回值数据必须经过特殊的格式封装 形式如下 xxxx(json串);
2.4 AJAX跨域的优化
问题1:客户端和服务器端的方法名称必须一致,否则程序调用失败.
问题2:利用javaScript中的src属性完成跨域请求,与之前编码习惯不同.代码编辑繁琐.
方案A:动态的获取前台方法名称,之后在后台动态拼接字符串.
src=http://manage.jt.com?callback=hello
一般使用约定俗成的callback封装函数名称.之后后台动态获取callback即可.
方案B:能够将javaScript中src属性的调用再次封装.封装为ajax的请求形式.
2.5 JSONP
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的
2.6 jQuery的JSONP调用
创建一个新页面JSONP.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP测试</title>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!");
$.ajax({
url:"http://manage.jt.com/web/testJSONP",
type:"get", //jsonp只能支持get请求
dataType:"jsonp", //dataType表示返回值类型
jsonp: "callback", //指定参数名称
jsonpCallback: "hello", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.id);
alert(data.name);
}
});
})
</script>
</head>
<body>
<h1>JSON跨域请求测试</h1>
</body>
</html>
JSONP请求形式
http://manage.jt.com/web/testJSONP?callback=hello
callback参数就是回调函数名称,默认为jQuery自动生成的随机函数名
在jt-manage中创建api接口(@RestController是@Controller和@ResponseBody联合的注解)
@RestController
public class JSONPController {
@RequestMapping("/web/testJSONP")
public JSONPObject jsonp(String callback) {
ItemCat itemCat = new ItemCat();
itemCat.setId(10086L);
itemCat.setName("jsonp测试调用!!!!");
return new JSONPObject(callback, itemCat);
}
}
我们重启项目,访问一下:可以看到callback的回调函数名称,这个名称和test.json的函数名称是一致的。
3 注册功能实现
我们访问一下注册页面http://www.jt.com/user/register
这里使用了nginx的域名代理哦
可以看到这里用户检测就用到了js跨域。我们上面分析了jt-sso项目只是单纯的注册,登录模块,而页面和样式文件都在jt-web模块中。
我们分析一下源码:
接口文档描述(此接口描述按照前后端分离的项目开发流程中,这个文档需要在开发前就应设计出来,这里我就直接提供在这。其他模块的接口文档以后在用到的时候再提供)
有了接口文档,节能清晰了解它的需求,也为开发带来效率。
我们创建一个jt-sso maven子工程
相应的配置可以查看我上传的git项目
在UserController编辑相关操作:
@RestController
@RequestMapping("/")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("user/check/{param}/{type}")
public JSONPObject checkUser(@PathVariable String param, @PathVariable Integer type, String callback) {
JSONPObject jsonpObject;
try {
boolean flag = userService.checkUser(param, type);
jsonpObject = new JSONPObject(callback, SysResult.success(flag));
} catch (Exception e) {
e.printStackTrace();
jsonpObject = new JSONPObject(callback, SysResult.fail());
}
return jsonpObject;
}
}
UserServiceImpl:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public boolean checkUser(String param, Integer type) {
String column = (type == 1) ? "username" : (type == 2 ? "phone" : "email");
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(column, param);
User user = userMapper.selectOne(queryWrapper);
return user == null ? false : true;
}
}
userMapper自行补全,但不能没有
重启服务,我们再看页面效果
成功调用,
可以看到回调函数是默认随机生成的,但也能成功,正是因为我们使用了JSONPObject
它能将需要的返回结果已jsonp的回调函数的格式进行返回。
4 微服务Dubbo
4.1 项目分析
-
httpClient
说明:httpClient是远程访问服务器最为常用的请求方式.但是请求的步骤繁琐.
优点:如果需要对参数进行特殊封装,首选httpClient. 安全性好
-
JSONP
JSONP主要解决跨域问题.
域:由于同源策略的约定.浏览器解析ajax发起的请求为跨域请求.
jsonp请求的具体内容,都可以被浏览器监控.所以一般请求如果涉密.不会采用jsonp的请求方式. -
代码优化
4.2 微服务思想
SOA思想
面向服务的架构(SOA) 是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
SOA思想是实现微服务编程的代码的架构形式.
微服务概念:微服务思想的前提基于分布式的思想.并且微服务要求项目能够独立运行(小).同时支持高可用.当出现问题时全部实现自动化的故障迁移(不要依赖第三方).
4.3 RPC
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
概括:PRC相当于是OSI模型中第四层协议,封装了TCP/UDP.使得用户调用更加的简化.最终实现了客户端访问服务器.
总结
这一节介绍了js跨域,和微服务相关概念。这也是为实现单点服务做准备。我们下一节着重介绍微服务的框架的相关技术以及如何配合项目使用