您现在的位置是:主页 > news > 做外贸怎么登陆外国网站/海外推广渠道都有哪些

做外贸怎么登陆外国网站/海外推广渠道都有哪些

admin2025/5/25 14:35:28news

简介做外贸怎么登陆外国网站,海外推广渠道都有哪些,做网站怎么接广告赚钱吗,电商网站建设课程注意事项 1.关于跨域的说明 跨域测试 同源策略 跨域方式:jsonp(get请求) cors jsonp:注意url格式,拼接回调函数名callback 浏览器缓存策略 随机数 jsopp优化—通过Ajax封装后发送请求 spring提供的针对jsonp返回特定格式的数据需要手动拼接字符串 优化----通过一个…

做外贸怎么登陆外国网站,海外推广渠道都有哪些,做网站怎么接广告赚钱吗,电商网站建设课程注意事项 1.关于跨域的说明 跨域测试 同源策略 跨域方式:jsonp(get请求) cors jsonp:注意url格式,拼接回调函数名callback 浏览器缓存策略 随机数 jsopp优化—通过Ajax封装后发送请求 spring提供的针对jsonp返回特定格式的数据需要手动拼接字符串 优化----通过一个…

注意事项

1.关于跨域的说明
跨域测试 同源策略 跨域方式:jsonp(get请求) cors
jsonp:注意url格式,拼接回调函数名callback 浏览器缓存策略 随机数
jsopp优化—通过Ajax封装后发送请求
spring提供的针对jsonp返回特定格式的数据需要手动拼接字符串 优化----通过一个Api对象拼接字符串
cors本质是Ajax,主流浏览器都支持需要定义配置类。
2. 京淘单点登录系统(没有页面,打jar包)
登录/注册 通用页面跳转—resful风格
在注册页面输入用户名,光标离开会自动效验是否存在数据业务–静态代码块
根据url快速定位页面
单点登录接口文档-----之检查数据是否可用
修改全局异常处理类
3 HttpClient
概念:可以再java代码内部使用httpClient发起http请求访问服务器获取资源的工具Api
案例测试:服务器和服务器之间通讯2种
跨域:解决简单地业务,查
HttpClient:复杂的业务
HttpClient的缺点。

1.关于跨域的说明(重要)

1.1 跨域访问测试

1.1.1 测试1: 同服务器测试(通域)

分析:
1.浏览器的网址信息: http://manage.jt.com/test.html
2. jax请求的地址信息: http://manage.jt.com/test.json
结论:
当浏览器地址与ajax请求的地址(协议://域名:端口)相同时,可以实现正常的业务调用。

问题:网站地址为什么通常是用域名而不是用ip进行访问?
在互联网中,每个机器设备都会有唯一的标识符,IP地址。但是记忆IP地址和身份号码类似也是一串长长的数字,十分不方便人们记忆。于是,出现了域名,来代替复杂的IP地址,方便我们快速访问网址。
所以,企业网上建站时,最先需要购买域名。
而关于域名为什么要付费使用,是因为域名统一由域名管理局管理,管理是需要成本的,如技术成本、人力成本等。

测试步骤:
1).页面代码分析.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title><!--引入js函数类库-->
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script><!--引入类库之后执行的js代码-->
<script type="text/javascript">/*文档就绪事件函数*/$(function(){$.get("http://manage.jt.com/test.json",function(data){alert(data.name);})})
</script>
</head>
<body><h1>JSON跨域请求测试</h1>
</body>
</html>

在这里插入图片描述

{"id":"1","name":"tom"}

在这里插入图片描述
2).访问效果.
在这里插入图片描述

1.1.2 测试2: 不同的服务器测试(跨域)

说明:
1.浏览器的网址信息: http://www.jt.com/test.html
2.ajax请求的地址信息: http://manage.jt.com/test.json
结论:
域名地址不相同时请求不能正常获取响应的结果.

步骤:
把相同的页面(test.html)放到前台系统,启动前台系统再次进行访问测试(前后台都要启动)可以看出不能发送Ajax请求。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.2 浏览器同源策略介绍

说明:
浏览器在解析ajax时,如果发现请求的协议名称://请求的域名:请求的端口号与网址的地址都相同的时满足同源策略的规定,浏览器可以正确的解析返回值,该访问称之为同域访问,该策略叫做同源策略。但是如果违反了同源策略中的任意一条,则叫做跨域访问,浏览器出于安全性的考虑,不予解析返回值。

概括: 浏览器解析ajax时,由于请求违反了同源策略则称之为跨域请求,反之称为同源策略。

在这里插入图片描述
注意:
1).2个关键词 : 浏览器 Ajax
2). 重定向是服务器解析所以不是跨域.
在这里插入图片描述

1.3 常见跨域实现方式1–JSONP

1.3.1 JSONP实现跨域的原理(有难度)

思路:
1.利用javascrpit中的src属性实现跨域请求.
2.自定义回调函数 function callback(xxxx);
3.将返回值结果进行特殊的格式封装 callback(json);
4.由于利用src属性进行调用 所以只能支持get请求类型.

测试步骤:
1).页面js编辑:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>	<script type="text/javascript">/*JS是解释执行的语言  *//*定义回调函数  */function hello(data){alert(data.name);}</script><!--该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>

在这里插入图片描述
2). json数据

hello({"id":"1","name":"tom"})

在这里插入图片描述
3). 启动前台 后台再次测试----成功发送ajax请求,跨域成功。
在这里插入图片描述

步骤说明:
1.javaScript中的src属性不受同源策略的约束.可以获取远程服务器数据.

<!--该json一直保存到浏览器中等待调用,但是没有函数名称无法调用    即,通过src调用想要别人调的通必需有名字  --><script type="text/javascript" src="http://manage.jt.com/test.json"></script>

2.自定义回调函数 名称任意 后期这个函数有人帮你封装好了.

/*定义回调函数  */function hello(data){alert(data.name);}

3.将返回值结果进行特殊的格式封装 callback(JSON); callback:回调函数

hello({"id":"1","name":"tomcat猫"})

1.3.2 JSONP概念

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的

1.3.3 JSONP优化–通过Ajax进行封装

说明:利用js的script标签的src属性发起请求不方便,需要自定义回调函数,封装特殊格式的返回值等太过麻烦,如何简化步骤呢?
:可以封装为ajax调用方式(底层原理没有变)。

1.3.3.1 编译页面发送ajax请求

Ajax调用方式分析:使用和普通的ajax方式相同。
1).页面js

<!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,不然变为普通的Ajax调用)//jsonp: "callback",    //指定参数名称//jsonpCallback: "hello",  //指定回调函数名称success:function (data){   //data经过jQuery封装返回就是json串console.log(data);//alert(data.id);//alert(data.name);//转化为字符串使用//var obj = eval("("+data+")");//alert(obj.name);}	});	})
</script>
</head>
<body><h1>JSON跨域请求测试</h1>
</body>
</html>

在这里插入图片描述
2).请求url的2个特殊参数分析。
在这里插入图片描述
callback:指定回调函数名,需要和封装的特定的返回值的名称保持一致,实现步骤为:在url地址后多拼接一个参数,代表回调函数名,默认名为callback=xxxxxxxxxxxx随机生成。并且把这个动态生成的名字当作参数传到后台服务器,之后在进行数据获取的时候动态解析这个参数名字,最后进行拼接成callback+json的结构。

随机数:因为浏览器缓存策略的原因,如果第二次方送相同的请求会走缓存。但是如果第二次业务数据有改动执行的请求还是原来的缓存显然不合适,所以一般会在js中拼接一个不影响业务逻辑的随机数来区分不同的请求。

3).callback=xxxxxx参数名和value的值可以自己指定。

在这里插入图片描述
在这里插入图片描述

1.3.3.2 编辑后台Controller返回数据

这是web发送过来的请求访问manage服务器
在这里插入图片描述

package com.jt.web.controller;import com.jt.pojo.ItemDesc;
import com.jt.util.ObjectMapperUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class JSONPController {/*** 测试跨域访问是否成功* url地址: http://manage.jt.com/web/testJSONP?callback=jQuery111106536880527642785_1600138715329&_=1600138715330* 参数:没有可以不接,因为每次都会自己拼接一个callback,而返回值恰好也需要方法名封装,所以可以当做参数直接传递。* 返回值的应该是经过特殊格式封装的数据.  callback(JSON)*/@RequestMapping("/web/testJSONP")public String  jsonp(String callback){ItemDesc itemDesc = new ItemDesc();//编译返回值数据itemDesc.setItemId(100L).setItemDesc("跨域测试成功!!!!");String json = ObjectMapperUtil.toJSON(itemDesc);//对象转化为jsonreturn callback+"("+json+")";}
}

1.3.3.3 优化字符串拼接----重新编辑Controller

package com.jt.web.controller;import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.ItemDesc;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class JSONPController {/** 优化手动拼接写发:* 测试跨域访问是否成功* url地址: http://manage.jt.com/web/testJSONP?callback=jQuery111106536880527642785_1600138715329&_=1600138715330* 返回值的应该是经过特殊格式封装的数据.  callback(JSON)* JSONPObject参数说明:*  1.function 回调函数名称*  2.返回的对象之后可以被转化为JSON*/@RequestMapping("/web/testJSONP")public JSONPObject jsonp(String callback){ //spring提供的ItemDesc itemDesc = new ItemDesc();itemDesc.setItemId(100L).setItemDesc("API测试!!!");return new JSONPObject(callback, itemDesc);}
}

在这里插入图片描述

1.3.3.4 访问测试

在这里插入图片描述
控制台输出:
在这里插入图片描述

1.3.4 原理

在这里插入图片描述

1.4 常见跨域实现方式2–CORS跨域方式

1.4.1 CORS跨域说明

说明:当下的主流的浏览器默认支持cors跨域的形式,但是需要服务器添加响应的信息,否则浏览器不支持数据的获取。
HEAD、GET、POST
在这里插入图片描述

1.4.2 编辑CORS配置类(common)

谁想要跨域就放在那个项目,因为用的比较多所以放在common中。
在这里插入图片描述

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 {/*** 在后端 配置cors允许访问的策略* 方法说明:*      1.addMapping(/**) 允许什么样的请求可以跨域: /*代表一级目录  /**代表所有请求的所有目录*      2.allowedMethods("*") 定义允许跨域的请求类型: *代表所有*      3.allowedOrigins("*")允许那个网址可以访问:*代表可以允许任意的域名,写具体的网址只能代表一个*      4.allowCredentials(true) 跨域时是否允许携带cookie等参数*      5.maxAge(1800)设定请求长链接超时时间(跨域之前会先进行询问是否允许跨域)*/@Overridepublic void addCorsMappings(CorsRegistry registry) {//允许策略的标识符registry.addMapping("/**").allowedMethods("GET","POST").allowedOrigins("*").allowCredentials(true).maxAge(1800);//30分钟}
}

1.4.3 cors跨域测试

在web前台发送请求到后台,如果能够访问代表跨域成功。
1).页面js
在这里插入图片描述

2).JSON数据格式
在这里插入图片描述
3).访问测试
在这里插入图片描述

1.4.4 关于跨域的总结

1).jsonp
jsonp本质利用javaScript中的src属性的get请求实现的跨域.
返回值必须经过特殊的格式封装.
2).cors
cors本质是Ajax,服务端策略。
需要在服务端添加响应头信息,指定哪些服务器允许访问。

2. 京淘单点登录系统

2.1 通用页面跳转

2.1.1 业务分析

需求说明:说明:当用户点击登录/注册按钮时 需要跳转到指定的页面中.
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
1.登录的url地址

http://www.jt.com/user/login.html

2.注册的url地址

http://www.jt.com/user/register.html

2.1.2 编辑UserController(web项目中)

在这里插入图片描述

package com.jt.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Controller //由于设计到页面跳转功能.
@RequestMapping("/user")
public class UserController {/*** 通用页面跳转实现* 1.http://www.jt.com/user/login.html       login.jsp页面* 2.http://www.jt.com/user/register.html    register.jsp页面* restFul方式: 1.动态获取url中的参数,之后实现通用的跳转.*/@RequestMapping("/{moduleName}")//resful风格需要加上这个注解public String module(@PathVariable String moduleName){return moduleName;}}

2.1.3 页面效果展现

再次点击登录 注册
在这里插入图片描述
在这里插入图片描述

2.2 创建JT-SSO项目

2.2.1 JT-SSO项目说明

作用:主要为jt-web的服务器提供用户的数据的支持,但凡涉及到user的CRUD操作都应该由该系统完成.
打包方式: jar包程序,此项目里面没有页面支持。
注意事项: 继承jt/ 依赖jt-common 添加插件.
端口号: 8093
在这里插入图片描述

2.2.2 创建项目(Maven)

在这里插入图片描述

2.2.3 编辑pom.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>jt-sso</artifactId><!--默认打包方式就是jar 所以不写也没有关系--><!--添加继承--><parent><artifactId>jt</artifactId><groupId>com.jt</groupId><version>1.0-SNAPSHOT</version></parent><!--添加依赖项--><dependencies><dependency><groupId>com.jt</groupId><artifactId>jt-common</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><!--添加插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.2.4 编辑User的POJO对象(common)

在这里插入图片描述

package com.jt.pojo;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;@TableName("tb_user")
@Data
@Accessors(chain = true)
public class User extends BasePojo {@TableId(type = IdType.AUTO)    //主键自增private Long id;private String username;    //用户名private String password;    //密码 需要md5加密private String phone;       //电话private String email;       //邮箱 注册页面没有这个选项 暂时使用电话代替邮箱}

2.2.5 实现JT-SSO代码结构

在这里插入图片描述
需求:通过sso.jt.com/findUserAll的请求,获取所有的用户表中的记录json串返回。

1).添加主启动类:
在这里插入图片描述


package com.jt;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.jt.mapper")//添加包扫描
public class SpringBootRun {public static void main(String[] args) {SpringApplication.run(SpringBootRun.class, args);}
}

2).配置文件
在这里插入图片描述

server:port: 8093servlet:context-path: /
spring:datasource:#引入druid数据源#type: com.alibaba.druid.pool.DruidDataSource#driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: rootmvc:view:prefix: /WEB-INF/views/suffix: .jsp
#mybatis-plush配置
mybatis-plus:type-aliases-package: com.jt.pojomapper-locations: classpath:/mybatis/mappers/*.xmlconfiguration:map-underscore-to-camel-case: truelogging:level: com.jt.mapper: debug

3).控制层:
在这里插入图片描述

package com.jt.controller;import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class UserController {@Autowiredprivate UserService userService;/*** 完成测试* 1.url地址:findUserAll* 2.参数:null* 3.返回值:List<User>*/@RequestMapping("/findUserAll")public List<User> findUserAll(){return userService.findUserAll();}}

4).service接口
在这里插入图片描述

package com.jt.service;import com.jt.pojo.User;import java.util.List;public interface UserService {List<User> findUserAll();
}

5).service接口实现类
在这里插入图片描述

package com.jt.service;import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserServiceImpl implements UserService{@Autowiredprivate UserMapper userMapper;@Overridepublic List<User> findUserAll() {return userMapper.selectList(null);}
}

6).mapper接口
在这里插入图片描述

package com.jt.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.User;public interface UserMapper extends BaseMapper<User> {
}

2.2.6 通过域名sso.jt.com实现访问

1).修改nginx之后重启nginx服务器.
在这里插入图片描述

#搭建jt-sso服务器server {listen 80;server_name sso.jt.com;location / {proxy_pass http://localhost:8093;}}

2).编辑hosts文件
在这里插入图片描述
3).配置主启动类访问测试
在这里插入图片描述

在这里插入图片描述

2.3 用户数据校验的分析

2.3.1 业务需求

说明:当用户在注册时,如果输入用户名,则应该向jt-sso单点登录系统发起请求,校验用户数据是否存在,如果存在则提示用户
在这里插入图片描述

2.3.2 单点登录业务接口文档

说明:这是单点登录业务接口文档中的关于检查数据是否可用的业务
在这里插入图片描述

2.3.3 页面url分析

说明:有接口文档已经可以开发代码了,但是这里作为学习前台也需要了解。
1).当输入完用户名后光标离开,会发送请求进行效验。
在这里插入图片描述
2).URL说明
在这里插入图片描述

2.3.4 检索页面JS

说明:通过url写死的地址定位到具体哪个页面发送的请求
步骤:
1).复制url中固定不变的地址。
在这里插入图片描述
2).在idea项目中进行检索:ctrl+h eclipse键位
之后在想要跳转的行数+enter
在这里插入图片描述

2.3.5 页面JS分析

在这里插入图片描述

 $.ajax({url : "http://sso.jt.com/user/check/"+escape(pin)+"/1?r=" + Math.random(),dataType : "jsonp",success : function(data) {      //状态信息:200 成功   状态信息:201 失败checkpin = data.data?"1":"0";if(data.status == 200){if (!data.data) {validateSettings.succeed.run(option);namestate = true;}else {validateSettings.error.run(option, "该用户名已占用!");namestate = false;}}else{//标识后台服务器运行异常validateSettings.error.run(option, "服务器正忙,请稍后!!!(我后台报错了我也不知道啥错!!!)");namestate = false;}}});

2.2.6 编辑jt-sso的UserController

说明:
1).由web中的页面发送请求到单点登录服务器sso中获取数据。
2).SysResult对象已经在common中的vo写过了。

package com.jt.controller;import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.User;
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;import java.util.List;@RestController
@RequestMapping("/user")//业务名称最好写类上
public class UserController {@Autowiredprivate UserService userService;/*** 业务说明: jt-web服务器获取jt-sso数据 JSONP跨域请求* url地址: http://sso.jt.com/user/check/{param}/{type}* 参数:    param: 需要校验的数据   type:校验的类型* 返回值:  SysResult对象* 真实的返回值: callback(SysResult的JSON)*/@RequestMapping("/check/{param}/{type}")//参数写在路径上 resful风格获取public JSONPObject checkUser(@PathVariable String param,@PathVariable Integer type,String callback){/*** 接口文档要求返回值为:* {*      status: 200  //200 成功,201 没有查到*      msg: “OK”  //返回信息消息*      data: false  //返回数据true用户已存在,false用户不存在,可以* }* 而系统vo---SysResult原来返回结果格式为:* {*      status:    //200成功   201 失败*      msg:       //服务器提示信息   成功  失败*      data:      //服务器返回值数据.* }*  可以看出这里要求data返回一个boolean类型的值而不是数据。*/boolean flag = userService.checkUser(param,type);SysResult.success(flag);//因为跨域需要特殊的返回值格式,所以需要进一步的封装  spring的优化字符串拼接写发:直接通过这个对象来接return new JSONPObject(callback, SysResult.success(flag));}/*** 完成测试* 1.url地址:findUserAll* 2.参数:null* 3.返回值:List<User>*/@RequestMapping("/findUserAll")public List<User> findUserAll(){return userService.findUserAll();}}

在这里插入图片描述

2.2.7 编辑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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.List;
import java.util.Map;@Service
public class UserServiceImpl implements UserService{@Autowiredprivate UserMapper userMapper;//定义map集合通过静态代码块赋值。private static Map<Integer,String> columnMap = new HashMap<>();static {columnMap.put(1, "username");columnMap.put(2, "phone");columnMap.put(3, "email");}/*** 判断依据:  根据用户名查询 如果结果>0 用户已存在.* 即:如果根据用户名进行查询返回值为查询的记录就代表* 这个数据存在,而不在乎是谁.* @param param   需要校验的数据* @param type    校验的类型 1username 2phone 3 email 6789910* @return*/@Overridepublic boolean checkUser(String param, Integer type) {/*** 1.需要将type类型转化为 具体字段信息  1=username  2=phone  3=email* 解释:因为用户传递进来的是 1 2 3这样具体的数字,而数据库库存的是这些数字对* 应的字段,所以需要进行转换查询。* 2.如何高效率的转化???* 如果采用普通的if判断 switch判断性能太低----可以用静态代码块,在类加载时就存在了。** */String column = columnMap.get(type);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq(column, param);Integer count = userMapper.selectCount(queryWrapper);//得到的结果 有值就是1 没值就是0return  count > 0 ? true :false;// 是1大于0代表有值返回true已存在 是0不大于0代表没有值返回false不存在用户}@Overridepublic List<User> findUserAll() {return userMapper.selectList(null);}}

在这里插入图片描述

2.2.8 页面效果测试

说明:启动web sso服务器,因为admin123在数据库存在所以只要光标离开就会提示用户已被占用。
在这里插入图片描述

2.2.9 修改全局异常处理机制

问题说明:
后端(不是后台,代表所有的服务器)服务器执行出错时,会执行全局异常的处理.但是JSONP的请求的调用要求 返回值类型 callback(JSON)结构.所以需要重构全局异常处理的返回值结构类型.
重构前:
在这里插入图片描述

重构后:
在这里插入图片描述

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;//@ControllerAdvice  //拦截controller层(因为mapper层和service层异常最终抛给controller层,所以拦截控制层最合适。)
//@ResponseBody 与页面交互都是json型的数据
@RestControllerAdvice   //定义全局异常的处理类   AOP=异常通知(底层封装好了)
public class SystemAOP {/***  定义全局异常的方法  当遇到了什么异常时,程序开始执行   参数一般class类型*  如果一旦发生异常,则应该输出异常的信息,之后返回错误数据即可.**  解决跨域全局异常处理的规则: 京淘项目的跨域都是使用JSONP.   http://xxxx?callback=xxxxx*  所以如果请求中携带了callback参数 则认为是JSONP跨域请求.*  难点: 如何获取callback参数呢??*  一般在控制层可以通过HttpServletRequest(请求头对象)获取url中携带的参数。*  思路:*  因为整个项目一旦出现异常就会走这个类,所以可以根据url是否携带callback进行判断,*  如果有callback应该返回跨域失败的异常处理方法,如果没有callback参数代表返回普通请求异常处理失败的方法。*/@ExceptionHandler({RuntimeException.class}) //多个不同类型的异常(如io,sql),写法:{RuntimeException.class,xxx,xxx}public Object systemAop(Exception e, HttpServletRequest request){e.printStackTrace();String callback = request.getParameter("callback");if (StringUtils.isEmpty(callback)) {//常规方法调用方式return SysResult.fail();} else {//证明是jsonp跨域请求return new JSONPObject(callback, SysResult.fail());}}
}

访问测试:因为修改的是common所以后端服务器都要重启。
在这里插入图片描述
在这里插入图片描述

3 HttpClient

3.1 业务需求

业务说明:当做某些操作时可能会对数据进行业务加工,之后由服务器和服务器之间形成通讯。eg:用户在网上买东西需要付款,付款的后台执行流程是,用户通过浏览器访问支付页面的服务器对数据进行加工,再把数据传给银行的服务器,最后由银行服务器返回结果。

为什么要对数据进行加工??
因为银行服务器再进行一些数据接收时对一些参数的格式有要求。直接通过跨域方式这些数据都写死在js里不方便。解决:用户通过浏览器发送请求交给后台服务器去处理,而后台服务器在内部把数据进行加工,然后在远程传给银行服务器。

跨域能解决吗??
不能,跨域是通过浏览器解析ajax请求,即通过浏览器直接访问银行服务器,对数据不能加工,银行对这些普通的数据格式没办法接收,所以跨域不能解决问题。跨域因为不能对数据进行加工,账户密码都会在传输过程中暴露,不安全
在这里插入图片描述
总结:
1).跨域访问只能解决一些简单地问题如:查
执行流程:前端服务器发送ajax请求(通过页面js),经过浏览器解析发送给后端服务器进行调用(controller—service----mapper层级调用在返回数据)。
2).httpClient远程调用更加安全,可以对数据加工后再发送请求
执行流程:前端代码发送的ajax请求先经过本地服务器进行参数加工(controller–service),将加工好的参数在传给后台服务器进行调用(controller–service–mapper)。

在这里插入图片描述

3.2 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)

总结: 在java代理内部可以使用httpClient发起http请求访问服务器获取资源.(工具API)

3.3 HttpClient入门案例

注意:将来在SpringCloud中会有更高级的Api对HttpClient的Api进行封装,这个更高级的Api底层就是HttpClient的Api.

3.3.1 导入jar包

<!--添加httpClient jar包 --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency>

在这里插入图片描述

3.3.2 入门案例(web里面)

在这里插入图片描述

package com.jt.test;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 {/*** 要求:在java代码内部,获取百度的页面.* 实现步骤:*  1.确定目标地址: https://www.baidu.com/*  2.创建httpClient客户端对象*  3.创建请求类型*  4.发起http请求.并且获取响应的结果.之后判断状态码是否为200 如果等于200则请求正确(因为请求不一定成功)*  5.如果请求正确则动态获取响应值信息.之后进行数据的再次加工....*  */@Testpublic void test01(){//1.确定地址String url = "https://www.baidu.com/";//2.创建一个默认的请求对象    注意导包apacheHttpClient httpClient = HttpClients.createDefault();//3.创建请求类型  发送get请求:HttpGet  post:HttpPost  put:HttpPutHttpGet get = new HttpGet(url);try {//3.1执行请求,因为请求不一定能‘发送’成功,所以需要处理异常 try-catch/throws,返回值为HttpResponseHttpResponse httpResponse = httpClient.execute(get);//4.判断状态码是否正确 因为请求不一定能成功int statusCode = httpResponse.getStatusLine().getStatusCode();//4.1获取状态码if(statusCode == 200){  //4.2表示请求正确//4.3获取服务器的全部响应信息(json/html/xml/xxxx)HttpEntity httpEntity = httpResponse.getEntity();//4.4 一般会把这个实体对象转化为字符串使用,转换的时候需要指定编码 否则会乱码String result = EntityUtils.toString(httpEntity,"UTF-8");//5.获取之后可以执行业务处理......System.out.println(result); //获取的应该是一个页面,页面的本质是html}else{//如果请求不成功打印一下状态码信息。System.out.println(httpResponse.getStatusLine().getStatusCode());}} catch (IOException e) {e.printStackTrace();}}
}

运行的结果:
在这里插入图片描述

3.4. HttpClient加强案例

3.4.1 需求说明:

用户通过网址 http://www.jt.com/getItems 要求采用httpClient方式,获取jt-manage中的商品信息,后json串的形式展现.
jt-web服务器访问jt-manage时的网址 http://manage.jt.com/getItems.

3.4.2 编辑前台 HttpClientController(web)

在这里插入图片描述

package com.jt.controller;import com.jt.pojo.Item;
import com.jt.service.HttpClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class HttpClientController {@Autowiredprivate HttpClientService httpClientService;/*** 获取后端manage中的商品数据信息*/@RequestMapping("/getItems")public List<Item> getItems(){return httpClientService.getItems();}}

3.4.3 编辑前台 HttpClientService(web)

在这里插入图片描述

package com.jt.service;import com.jt.pojo.Item;
import com.jt.util.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.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@Service
public class HttpClientServiceImpl implements HttpClientService{@Overridepublic List<Item> getItems() {//前端访问后端在java代码内部只能通过httpclient的方式List<Item> itemList = new ArrayList<>();//准备集合转化为对象//1.定义远程访问网址String url = "http://manage.jt.com/getItems";HttpClient httpClient = HttpClients.createDefault();HttpGet httpGet = new HttpGet(url);try {HttpResponse httpResponse = httpClient.execute(httpGet);if(httpResponse.getStatusLine().getStatusCode() == 200){String result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");/*** result是jt-manage为jt-web返回的List<Item>的JSON串,* 而现在需要返回的是List<Item>类型的集合所以需要转换*/if(!StringUtils.isEmpty(result)){//不为空才进行处理itemList = ObjectMapperUtil.toObject(result, itemList.getClass());}}} catch (IOException e) {//把异常信息输出到控制台e.printStackTrace();//把检查型异常转化为运行时异常抛出throw new RuntimeException(e);}return itemList;}
}

3.4.5 编辑后台 HttpClientController(manage)

在这里插入图片描述

package com.jt.web.controller;import com.jt.pojo.Item;
import com.jt.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class HttpClientController {@Autowiredprivate ItemService itemService;/*** url请求地址: http://manage.jt.com/getItems*/@RequestMapping("/getItems")public List<Item> getItems(){return itemService.getItems();}
}

3.4.6 编辑后台 HttpClientService(manage)

在这里插入图片描述

	@Overridepublic List<Item> getItems() {return itemMapper.selectList(null);}

3.4.7 页面效果展现

在这里插入图片描述

3.5 HttpClient调用缺点

缺点:代码调用的层级很多,如何简化呢?
答: SOA(面向服务的架构)。
在这里插入图片描述