1 关于JSONP知识说明
1.1 JSONP工具API说明
1.1.1 JSONP页面说明
$.ajax({
url:"http://manager.jt.com/web/testJSONP",
type:"get", //jsonp只能支持get请求 src只能进行get请求.
dataType:"jsonp", //dataType表示返回值类型 必须标识
//jsonp: "callback", //指定参数名称
jsonpCallback: "hello", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.itemId);
alert(data.itemDesc);
}
});
1.1.2 Ajax请求方式
1.1.3 服务器处理跨域请求
package com.jt.web.controller;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.ItemDesc;
import com.jt.unit.ObjectMapperUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController //json字符串
public class JSONPController {
@RequestMapping("/web/testJSONP")
public JSONPObject jsonp(String callback){
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(101L).setItemDesc("我是商品详情信息");
return new JSONPObject(callback, itemDesc);
}
}
2. CORS跨域访问说明
2.1CORS说明
CORS,全称Cross-Origin Resource Sharing [1] ,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。
知识回顾:
JSONP: 用户利用jsonp向服务器端动态获取数据的过程. 主体用户.
CORS: 服务器是否允许客户端访问的技术. 主体服务器.
2.2 CORS原理说明
用户可以向普通的ajax请求一样发起跨域请求. get/post/put/delete,由于当下的跨域的业务比较常见,所有的主流的浏览器默认支持跨域. CORS核心需要配置服务器端是否允许跨域
2.2.1 常规ajax跨域请求
1).页面标识
<script type="text/javascript">
$(function(){
alert("我执行了AJAX");
$.get("http://manager.jt.com/test.json",function(data){
alert(data.name);
})
})
</script>
2).页面报错信息. 表示服务器端暂时不允许跨域.
2.3 服务器实现CORS跨域
说明: 服务器端如果需要实现CORS跨域请求,则需要在服务器端标识允许跨域的网址即可.
2.3.1 编辑页面实现跨域请求
编辑jt-web 中的test.html页面信息.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>
<script type="text/javascript" src="http://manager.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
alert("我执行了AJAX");
$.get("http://manager.jt.com/corsjson.json",function(data){
alert(data.name);
})
})
</script>
</head>
<body>
<h1>JSON跨域请求测试</h1>
</body>
</html>
2).编辑json数据
2.3.2 编辑CORS跨域
说明:为了以后能够实现通用,则在jt-common中添加cors操作.
package com.jt.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration //标识我是一个配置类
public class CorsConfig implements WebMvcConfigurer {
//扩展跨域请求的方法
@Override
public void addCorsMappings(CorsRegistry registry) {
//1.允许什么样的请求进行跨域
//
@RequestMapping("/getMsg")
public String getMsg(){
return "sso单点登录系统正常";
}
}
3.2.6编辑Hosts文件
3.2.7 编辑nginx配置文件
修改nginx之后重启服务器.
# 配置前台服务器
server {
listen 80;
server_name sso.jt.com;
location / {
proxy_pass http://localhost:8093;
}
}
3.2.8.访问测试效果
3.3 完成用户信息校验
3.3.1 检查URL请求路径
3.3.2 检查JS
1).检索项目中的代码.
2).检查用户JSONP跨域请求
3.3.3 接口文档说明
3.3.4 编辑jt-sso UserController
package com.jt.controller;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.service.UserService;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//服务器端程序要求返回的都是JSON 所以使用
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getMsg")
public String getMsg(){
return "sso单点登录系统正常";
}
@RequestMapping("/check/{param}/{type}")
public JSONPObject checkUser(@PathVariable String param,
@PathVariable Integer type,
String callback){
//1.校验数据库中是否存在该数据
boolean flag = userService.checkUser(param,type); //存在true 不存在false
return new JSONPObject(callback, SysResult.success(flag));
}
}
3.3.5 编辑jt-sso UserService
package com.jt.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import jdk.nashorn.internal.codegen.TypeMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService{
//采用工具API形式动态获取
private static Map<Integer,String> typeMap = new HashMap<>();
static { //类加载时就要执行 只执行一次
typeMap.put(1,"username");
typeMap.put(2,"phone");
typeMap.put(3,"email");
}
@Autowired
private UserMapper userMapper;
@Override
public boolean checkUser(String param, Integer type){
//1.根据参数类型获取校验的类型 column
String column = typeMap.get(type);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(column, param);
int count = userMapper.selectCount(queryWrapper);
return count==0?false:true;
}
}
3.3.6 页面效果展现
3.3.7 全局异常处理机制
package com.jt.aop;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.vo.SysResult;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
@RestControllerAdvice //定义异常处理的通知. 只拦截Controller层抛出的异常. 并且返回值JSON串
public class SystemExceptionAOP {
@ExceptionHandler(RuntimeException.class)
public Object fail(Exception e, HttpServletRequest request){
//1.获取用户的请求参数
String callback = request.getParameter("callback");
//2.判断参数是否有值
if(StringUtils.isEmpty(callback)){
//用户请求不是jsonp跨域访问形式
//打印异常信息
e.printStackTrace();
return SysResult.fail();
}else{
//jsonp的报错信息.
e.printStackTrace();
return new JSONPObject(callback, SysResult.fail());
}
}
}
3.3.8 重构页面JS
$.ajax({
url : "http://sso.jt.com/user/check/"+escape(pin)+"/1?r=" + Math.random(),
dataType : "jsonp",
success : function(data) { //sysResultJSON
checkpin = data.data?"1":"0";
//判断jsonp校验是否正常
if(data.status == 200){
if (!data.data) { //false
validateSettings.succeed.run(option);
namestate = true;
}else {
validateSettings.error.run(option, "该用户名已占用!");
namestate = false;
}
}else{
validateSettings.error.run(option, "服务器异常,请稍后重试!!!!");
namestate = false;
}
}
});
4. HttpClient
4.1 HttpClient介绍
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 .6(2015-09-11)
SpringCloud跨域中实现远程数据访问底层实现就是httpClient.
httpClient作用: 在java代码内部发起http请求.
4.2 HttpClient入门案例
4.2.1 引入httpClient工具包
<!--添加httpClient jar包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
4.2.2 HttpClient入门案例
package com.jt;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
public class TestHttpClient {
@Test
public void test01(){
HttpClient httpClient = HttpClients.createDefault();
String url = "https://www.cctv.com";
HttpGet get = new HttpGet(url);
try {
HttpResponse httpResponse = httpClient.execute(get);
//获取返回值状态信息
int status = httpResponse.getStatusLine().getStatusCode();
if(status == 200){
//请求正确的. 获取响应结果
HttpEntity entity = httpResponse.getEntity(); //获取响应对象的实体信息.
//将实体对象转化为用户能够识别的字符串
String result = EntityUtils.toString(entity,"UTF-8");
System.out.println(result);
}else{
System.out.println("httpClient调用异常.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.3 HttpClient高级案例
4.3.1 业务说明
用户通过 http://www.jt.com/user/httpClient/saveUser/{username}/{password} 访问服务器.要求利用httpClient技术将用户信息保存到jt-sso中.
发送url请求路径: http://sso.jt.com/user/httpClient/saveUser?username=xxxx&password=xxxx
实现数据传递.
在jt-sso中完成数据入库操作.
4.3.2 编辑jt-web Controller
package com.jt.controller;
import com.jt.pojo.User;
import com.jt.service.HttpClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController //学习httpCLient调用规范
public class HttpClientController {
@Autowired
private HttpClientService httpClientService;
@RequestMapping("/user/httpClient/saveUser/{username}/{password}")
public String saveUser(User user){ //参数接收与对象的属性必须保持一致.可以自动赋值springmvc
httpClientService.saveUser(user);
return "httpClient测试成功!!!";
}
}
4.3.2 编辑jt-web Service
package com.jt.service;
import com.jt.pojo.User;
import com.jt.unit.ObjectMapperUtil;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.springframework.stereotype.Service;
import java.io.IOException;
@Service
public class HttpClientServiceImpl implements HttpClientService{
//位置jt-web 不能直接链接数据库 需要将数据传递给sso.jt.com
@Override
public void saveUser(User user) {
//1.将user对象转化为json http://xxxxx?id=1&name=xxx
String userJSON = ObjectMapperUtil.toJSON(user);
String url = "http://sso.jt.com/user/httpClient/saveUser?username="
+user.getUsername()+"&password="+user.getPassword();
//get请求
HttpClient httpClient = HttpClients.createDefault();
HttpGet get = new HttpGet(url);
try {
HttpResponse httpResponse = httpClient.execute(get);
if(httpResponse.getStatusLine().getStatusCode() != 200){
throw new RuntimeException("请求错误");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("请求错误");
}
}
}
4.3.3 编辑jt-sso Controller
@RequestMapping("/httpClient/saveUser")
public SysResult saveUser(User user){
userService.saveHttpCleint(user);
return SysResult.success();
}
4.3.4 编辑jt-sso Service
@Override
public void saveHttpCleint(User userPOJO) {
userPOJO.setEmail("111222333@qq.com") //数据库中要求email和phone是非空的 暂时写死
.setPhone("1311112222");
userMapper.insert(userPOJO);
}
4.3.5 页面效果展现
测试URL地址: http://www.jt.com/user/httpClient/saveUser/admin123456/12345678
作业
1.跨域和httpClient调用区别!!! 相同点 不同点
2.RPC