【前端】前后端通信方法与差异(未完待续)

系列文章

【Vue】vue增加导航标签
本文链接:https://blog.csdn.net/youcheng_ge/article/details/134965353

【Vue】Element开发笔记
本文链接:https://blog.csdn.net/youcheng_ge/article/details/133947977

【Vue】vue,在Windows IIS平台部署
本文链接:https://blog.csdn.net/youcheng_ge/article/details/133859117

【Vue】vue2与WebApi跨域CORS问题
本文链接:https://blog.csdn.net/youcheng_ge/article/details/133808959

【Vue】nvm安装教程(解决npm下依赖包版本冲突)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/132896207

【Vue】vue开发环境搭建教程(详细)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/132689006

【Vue】日期格式化(全局)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/135017332

【Vue】elementUI表格,导出Excel
本文链接:https://blog.csdn.net/youcheng_ge/article/details/135018489

【Vue】el-date-picker日期范围组件(本周、本月、上周)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/135088143

【前端】前后端通信方法与差异
本文链接:https://blog.csdn.net/youcheng_ge/article/details/135153985



前言

本专栏为 前端【Vue】专栏,主要介绍Vue知识点。对于刚进入计算机世界的学生来说,学习课本上的知识是远远不够的,并且国内教材偏旧,所以需要我们通过互联网自主学习。
这里普及一个知识:HTML已不仅仅只能开发 Web,也可以开发移动端(AndroidiOS),所以本专栏也会介绍 移动端的开发。
我个人将移动端开发,分为两大方向:

①原生开发
最早一批,使用安卓开发工具包(Android SDK)和Java语言来开发App的方式。原生开发允许开发者充分利用安卓平台的功能和特性,以及庞大的安卓开发社区资源。但缺点就是门槛高、需要适配不同尺寸的屏幕、测试繁琐,对开发人员技术要求高。

②混合开发(加壳方式)
当前热门,使用Web技术(网页三剑客HTML、CSS和JavaScript)开发App的方式,使用 vue.jsnode.jsAngular.jsReact.jsapi.js等框架开发。混合开发具有较高的开发效率和跨平台的优势,由于使用Web技术进行 界面渲染样式丰富、屏幕适配(栅格技术自适应)效果好。但缺点就是对底层硬件调用库尚不完善,有时候会发生异常,对框架依赖较高,不过库在不断完善中,主要的相机、相册、GPS、存储调用是没有问题的。

Vue是前端开发中的一个分支,它基于标准 HTML、CSS 和 JavaScript 构建,学习Vue不可以速成,得先熟悉网页三剑客(HTML、CSS和JavaScript)。Vue是一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。
在这里插入图片描述

一、技术介绍

本文介绍前后端交互方法与差异,分享我项目中采用的 通信方法,分析它们参数的不同,以及接受参数注意点。

1.1 axios通信

描述:Axios(ajax i/o system)是一个基于 promise的网络请求库,相比于原生的XMLHttpRequest对象来说,简单易用;相比于jQuery,axios包尺寸小且提供了易于扩展的接口,是专注于网络请求的库。符合最新的ES规范。
使用技术:XMLHttpReques
使用范围:主要用于node.js的项目中
我的项目:我在vue项目使用,request.js 也是对 axios 封装。

1.2 ajax通信

描述:Ajax即Asynchronous Javascript And XML(异步JavaScript和XML),使用Ajax技术可以实现网页局部刷新
使用技术:XMLHttpReques
使用范围:一些原生HTML项目用的比较多
我的项目:手持端,安卓的开发,我使用的ajax通信。

1.3 XMLHttpRequest通信

后期补充
使用技术:XMLHttpReques

1.4 WebSockets通信

我暂时没有使用过,用到时补充

1.5 Shell通信

描述:shell终端通信,最初基于Linux脚本。我也不知道怎么描述,前端采用shell及其少,网络上的资料更少了,反正我们直接看代码吧,日后有资料了,我在补充。
使用技术:TCP/UDP
使用范围:暂无
我的项目:网上使用shell通信极其少,我用于外壳通信,外壳是windowform,我需要调用打印机。

二、项目源码

2.1 axios通信

具体参数可以查阅官网吧,我这里对 axios进行封装,定义成全局方法,为了项目使用的方便。

位置:src\utils\baseclass.js
代码:使用的vue开发的。

2.1.1 data中定义URL变量

SERVER_ADDRESS: CONFIG_URL.PLATFROM_CONFIG.baseURL,

CONFIG_URL.PLATFROM_CONFIG.baseURL 就是文件的URL地址,将文件放在 public目录下,不会被打包,节省很多事,你也不用考虑什么跨越代理转发(URL替换)等问题。
在这里插入图片描述
详情可以阅读下文:
【Vue】vue2与WebApi跨域CORS问题
本文链接:https://blog.csdn.net/youcheng_ge/article/details/133808959

2.1.2 methods中定义通信方法

    // 函数内容:发送消息
    // 函数版本: 0.0.0.1
    // 修改时间: 2023.08.01
    // ================================================
    // 注意事项
    // 1.
    // ================================================
    WebApiSendMessage(data) {
      // 发送消息
      return axios({
        url: this.SERVER_ADDRESS + '/Message',
        method: 'post',
        headers: { 'content-type': 'application/json; charset=utf-8' },
        data: data
      }).catch((err) => {
        if (err.response) {
          // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
          // 弹出提示
          MessageBox.confirm('请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围', {
            title: '信息提示',
            confirmButtonText: '确定',
            showCancelButton: false
          })
        } else if (err.request) {
          // 请求已经成功发起,但没有收到响应
          // `err.request` 在浏览器中是 XMLHttpRequest 的实例,
          // 而在node.js中是 http.ClientRequest 的实例

          // 弹出提示
          MessageBox.confirm('请求已经成功发起,但没有收到响应', {
            title: '信息提示',
            confirmButtonText: '确定',
            showCancelButton: false
          })
        } else {
          // 发送请求时出了点问题
          console.log('err', err.message)

          // 弹出提示
          MessageBox.confirm('发送请求时出问题', {
            title: '信息提示',
            confirmButtonText: '确定',
            showCancelButton: false
          })
        }
      })
    },

2.1.3 main.js中全局引入

// 全局混入自定义类
import baseclass from './utils/baseclass'
Vue.mixin(baseclass)

2.1.4 axios发送数据

代码解析:
1、onSubmit()就是页面提交按钮,rule经过规则验证没有问题后,执行SaveData()方法

// 提交数据
onSubmit() {
      this.$refs['postForm'].validate(valid => {
        if (valid) {
          this.SaveData()
        }
      })
    },
    SaveData() {
      // 消息数据
      const data = new this.WebApiData(1507)
      var postTable = []

      // 裸砂原料信息表
      var T_info = []
      T_info.push({
        裸砂原料编号: this.postForm.裸砂原料编号,
        报废备注: this.postForm.明细表[0].备注
      })
      // 裸砂半成品信息表
      var T_halfInfo = []
      const detaillength = this.postForm.明细表.length
      for (let i = 0; i < detaillength; i++) {
        let item = this.postForm.明细表[i]
        T_halfInfo.push({
          公司编号: this.postForm.公司编号,
          // 工厂名称: undefined,
          // 存货编码: undefined,
          // 采购订单编号: undefined,
          // 领用申请单编号: undefined,
          // 销售订单编号: undefined,
          // 供应商编号: undefined,
          裸砂原料编号: this.postForm.裸砂原料编号,
          待提存裸砂编号: this.postForm.待提纯裸砂编号,
          待分选裸砂编号: this.postForm.待分选裸砂编号,
          裸砂半成品编号: undefined,
          裸砂半成品类型: undefined,
          砂规格: item.砂规格,
          砂型号: item.砂型号,
          当前重量: item.当前重量,
          分选机编号: item.分选机编号
        })
      }

      // 裸砂分选流程表
      var T_flow = []
      for (let i = 0; i < detaillength; i++) {
        let item = this.postForm.明细表[i]
        T_flow.push({
          公司编号: this.postForm.公司编号,
          裸砂原料编号: this.postForm.裸砂原料编号,
          待提纯裸砂编号: this.postForm.待提纯裸砂编号,
          待分选裸砂编号: this.postForm.待分选裸砂编号,
          待分选裸砂重量: this.postForm.待分选裸砂重量,
          分选开始时间: this.postForm.分选开始时间,
          分选开始录入时间: this.postForm.分选开始录入时间,
          分选开始人编号: this.postForm.分选开始人编号,
          分选开始备注: this.postForm.分选开始备注,
          裸砂半成品规格: item.砂规格,
          裸砂半成品编号: undefined,
          裸砂半成品重量: item.当前重量,
          分选机编号: item.分选机编号,
          分选结束备注: item.备注,
          分批数量: detaillength
        })
      }

      //表
      postTable.push(
        T_info
      )
      postTable.push(
        T_halfInfo
      )
      postTable.push(
        T_flow
      )
      data.table = postTable

      // 发送消息
      this.WebApiSendMessage(data).then((result) => {
        console.log(result)
        this.MessageHandle(result)
      })
    },

2.1.5 axios接收数据

代码解析:
1、MessageHandle(result)接收后台返回的数据,注意看这里是 result.data

    // 返回消息处理
    MessageHandle(result) {
      // 数据解构
      const { sn, success, errCode, errMsg, data, keyValue, table } = result.data
      // 显示返回信息
      this.ShowMessage(errMsg)
      switch (sn) {
        case 1507:
          if (success) {
            this.reset()
            //执行打印任务,等外壳打印
            this.PrintHandle(data,104)
          } else {
            this.ShowMessage(errMsg)
          }
          break

        default:
          break
      }
    },

2.2 ajax通信

需要特别说明一下,原生jQuery下的ajax需要解决跨越问题,并且代码不够简洁。
而我使用的是 api.js 下的 ajax,不用过多理解,使用方法和参数几乎一模一样的,它仅仅是解决跨越问题,以及优化通信代码。

2.2.1 ajax通信库

位置:script\api.js
代码:原生HTML开发的,APICloud官网提供的库api.js 下载,或者查看我的底层库专栏。

2.2.2 ajax发送数据

代码解析:
1、Btn_OK 提交按钮,就是数据构造代码。
2、Content-Type是必须的,否则后端无法识别。

		Btn_OK: function () {
			const technologyId = model.data.daifenxuanluoshabianhao.trim();
			if (technologyId == "") {
				ShowToast("带分选裸砂编号,不为空!");
				return;
			}
			if (model.data.shaguige.trim() == "") {
				ShowToast("砂规格,不为空!");
				return;
			}
			if (model.data.fenxuanjibianhao.trim() == "") {
				ShowToast("分选机编号,不为空!");
				return;
			}
			if (Number(model.data.桶数) <= 0) {
				ShowToast("桶数,必须大于0!");
				return;
			}

			var postTable = [];
			// 裸砂原料信息表
			var T_info = [];
			T_info.push({
				裸砂原料编号: model.data.luoshayuanliaobianhao,
				报废备注: model.data.fenxuanjieshubeizhu
			});

			// 裸砂半成品信息表
			var T_halfInfo = []
			const detaillength = Number(model.data.tongshu);
			for (let i = 0; i < detaillength; i++) {
				T_halfInfo.push({
					公司编号: model.data.gongsibianhao,
					裸砂原料编号: model.data.luoshayuanliaobianhao,
					待提存裸砂编号: model.data.daitichunluoshabianhao,
					待分选裸砂编号: model.data.daifenxuanluoshabianhao,
					裸砂半成品编号: undefined,
					裸砂半成品类型: undefined,
					砂规格: model.data.shaguige,
					砂型号: model.data.shaxinghao,
					当前重量: model.data.dangqianzhongliang,
					分选机编号: model.data.fenxuanjibianhao
				})
			}

			// 裸砂分选流程表
			var T_flow = [];
			for (let i = 0; i < detaillength; i++) {
				T_flow.push({
					公司编号: model.data.gongsibianhao,
					裸砂原料编号: model.data.luoshayuanliaobianhao,
					待提纯裸砂编号: model.data.daitichunluoshabianhao,
					待分选裸砂编号: model.data.daifenxuanluoshabianhao,
					待分选裸砂重量: model.data.daifenxuanluoshazhongliang,
					分选开始时间: model.data.fenxuankaishishijian,
					分选开始录入时间: model.data.fenxuankaishilurushijian,
					分选开始人编号: model.data.fenxuankaishirenbianhao,
					分选开始备注: model.data.fenxuankaishibeizhu,
					裸砂半成品规格: model.data.shaguige,
					裸砂半成品编号: undefined,
					裸砂半成品重量: model.data.dangqianzhongliang,
					分选机编号: model.data.fenxuanjibianhao,
					分选结束备注: model.data.fenxuanjieshubeizhu,
					分批数量: model.data.tongshu
				});
			}
			postTable.push(
				T_info
			);
			postTable.push(
				T_halfInfo
			);
			postTable.push(
				T_flow
			);
			let data = {
				SN: 1507,
				userID: 'gyc',
				password: '123',
				clientIP: '127.0.0.1',
				windowsPCName: 'DESKTOP-95GJUJ1',
				windowsUserName: 'gyc',
				keyValue: {},
				table: postTable
			};
			model.SaveData(data);
		},

		SaveData: function (data) {
			api.showProgress({
				style: 'default',
				animationType: 'fade',
				title: '数据保存中,请稍候...',
				text: '',
				modal: true
			});

			//保存数据
			api.ajax({
				url: API_HOST + '/Api/Message',
				method: 'post',
				headers: {
					'Content-Type': 'application/json;charset=utf-8',//必须,否则后端无法识别
				},
				timeout: 180,
				returnAll: false,
				data: {
					body: data
				}
			}, function (ret, err) {
				api.hideProgress();
				if (ret) {
					MessageHandle(ret)
				}
				else {
					ShowToast(err.msg);
				}
			});
		}
	});

2.2.3 ajax接收数据

代码解析:
1、MessageHandle(result)后端返回数据的处理,注意看这里是 result,没有data层级。

	// 返回消息处理
	function MessageHandle(result) {
		// 数据解构
		const { sn, success, errCode, errMsg, data, keyValue, table } = result;

		// 显示返回信息
		ShowToast(errMsg);

		switch (sn) {
			case 1507:
				if (success) {
					reset();
					//执行打印任务,等外壳打印
					// if (this.bShowFX) {
					//   // 分选,出待分选标
					//   this.PrintHandleFX(data)
					// } else {
					//   // 不分选,出半成品标
					//   this.PrintHandleBCP(data)
					// }
				} else {
					ShowToast(errMsg);
				}
				break;

			default:
				break;
		}
	}

2.3 shell通信

2.3.1 shell发送请求

代码解析:
1、Shell.post()向外壳发送数据

 /**
  * 打印方法
  */
 PrintHandle(table,sn) {
   // 消息数据
   const data = new this.WebApiData(sn)

   // 转换格式,List<DataTable>
   var postTable = []
   postTable.push(
     table
   )
   data.table = postTable

   // 向外壳发送消息
   const strJSON = Shell.post(JSON.stringify(data))
 },

2.3.2 shell接收请求

//网页浏览器
public ChromiumWebBrowser browser;

CefSettings cefSetting = new CefSettings();
Cef.Initialize(cefSetting);
// 注册JsObj对象,实现JS调用C#
CefSharpSettings.WcfEnabled = true;
browser = new ChromiumWebBrowser(str_url);
browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
browser.JavascriptObjectRepository.Register("Shell", new JavaScriptFunction(this),
    isAsync: false, options: BindingOptions.DefaultBinder);
public string post(string strJSON)
{
	//数据初始化
	BaseWebApiDataReceive webApiData = JsonConvert.DeserializeObject<BaseWebApiDataReceive>(strJSON);
}

三、效果展示

3.1 axios效果

在这里插入图片描述

3.2 ajax效果

在这里插入图片描述

3.3 shell效果

效果看不到了,我打个断点,看一下前端传来的数据。
在这里插入图片描述
在这里插入图片描述

四、资源链接

(未完待续)

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Java中,泛型是一种强类型机制,它可以让你在编译时检查类型错误,从而提高代码的安全性和可读性。在使用泛型时,我们经常会遇到父类和子类的泛型转换问题。 首先,我们需要明确一点:子类泛型不能转换成父类泛型。这是因为Java中的泛型是不协变的。例如,如果有一个类A和它的子类B,那么List<A>和List<B>之间是不存在继承关系的。 下面我们来看一个例子: ```java public class Animal { //... } public class Dog extends Animal { //... } public class Test { public static void main(String[] args) { List<Animal> list1 = new ArrayList<>(); List<Dog> list2 = new ArrayList<>(); list1 = list2; // 编译错误 } } ``` 在这个例子中,我们定义了Animal类和它的子类Dog。然后我们定义了两个List,分别是List<Animal>和List<Dog>。如果将List<Dog>赋值给List<Animal>,会出现编译错误。这是因为List<Animal>和List<Dog>之间不存在继承关系。 那么,如果我们想要让子类泛型转换成父类泛型,应该怎么办呢?这时我们可以使用通配符来解决问题。通配符可以表示任意类型,包括父类和子类。例如,我们可以将List<Dog>赋值给List<? extends Animal>,这样就可以实现子类泛型转换成父类泛型了。 下面我们来看一个使用通配符的例子: ```java public class Animal { //... } public class Dog extends Animal { //... } public class Test { public static void main(String[] args) { List<Animal> list1 = new ArrayList<>(); List<Dog> list2 = new ArrayList<>(); list1 = list2; // 编译错误 List<? extends Animal> list3 = new ArrayList<>(); list3 = list2; // 正确 } } ``` 在这个例子中,我们定义了List<? extends Animal>来表示任意继承自Animal的类型。然后我们将List<Dog>赋值给List<? extends Animal>,这样就可以实现子类泛型转换成父类泛型了。 总结一下,Java中的泛型是不协变的,子类泛型不能转换成父类泛型。如果需要实现子类泛型转换成父类泛型,可以使用通配符来解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花北城

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值