① SpringMVC前后端分离交互传参详细教程-
温故而知新,本文为一时兴起写出,如有错误还请指正
本文后台基于SpringBoot2.5.6编写,前端基于Vue2 + axios和微信小程序JS版分别编写进行联调测试,用于理解前后端分离式开发的交互流程,如果没用过axios可以点我看之前的帖子
如果你没有学过SpringBoot也不要紧,把他看做成SpringMVC即可,写法完全一致(其实我不说你也发现不了)
本文主要讲前后端交互流程,力求帮助新人快速入门前后端分离式开发,不会讲关于数胡环境搭建部分的内容
在文章开头快速的过一遍SpringMVC接收参数的几种方式,一定要记住这几种方式,看不懂或不理解都没关系,后续会结合前端代码过一遍,这里就不过多解释了,直接上代码
细心的人应该留意到了,最后使用变量接收参数的时候只接收了 username 这一个值,并没有接收 password ,作为扩展在这里解释一下, 不看也可以,看了不理解也没关系,知道这个事儿就够了,以后接触多了就理解了
如果请求参数放在了请求体中,只有参数列表第一个变量能接收到值,这里需要站在Servlet的角度来看:
可以看到请求体内容是存到了 InputStream 输入流对象中,想要知道请求体中的内容是什么必须读流中的数据,读取到数据后会将值给第一个变量,而流中的数据读取一次之后就没了,当第二个变量读流时发现流已经被关闭了,自然就接收不到
SpringMVC回顾到此为止,只需要记住那三种方式即可,在前后端交互之前先在Controller中写个测试接口
这个接口对应的是GET类型的请求,这里直接在浏览器地址栏访问测试一下:
这里推荐一个Chrome浏览器的插件 JSONView ,它可以对浏览器显示的JSON数据进行格式化显示,推荐的同时也提个醒,安装需谨慎,如果JSON数据量太大的话页面会很卡
之前已经写好一个GET请求的测试接口了,这里就在前端写代码访问一下试试看
代码已经写完了,接下来打开页面试一下能不能调通:州凳
可以看到请求代码报错了,查看报错信息找到重点关键词 CORS ,表示该请求属于 跨域请求
什么是跨域请求?跨域请求主要体现在跨域两个字上,当发起请求的客户端和接收请求的服务端他们的【协议、域名、端口号】有任意一项不一致的情况都属于跨域请求,拿刚刚访问的地址举例,VUE页面运行在9000端口上,后台接口运行在8080端口上,端口号没有对上所以该请求为跨域请求
如果在调试的时候仔细一点就会发现,虽然前端提示请求报错了,但是后端还是接收到请求了,那为什么会报错呢?是因为后端返回数据后,浏览器接收到响应结果发现该请求跨域,然后给我们提示错误信息,也就是说问题在浏览器这里
怎样才能让浏览器允许该请求呢?我们需要在后端动点手脚,在返回结果的时候设置允许前端访问即可
首先配置一个过滤器,配置过滤器有很多种实现的方法,我这里是实现Filter接口
过滤器创建完成了,回来看前端提示的报错信息为 Access-Control-Allow-Origin ,意思是允许访问的地址中并不包含当前VUE的地址,那么我们就在响应结果时将VUE的地址追加上
添加完成后重启项目后台就会发现请求已经成功并且拿到了返回值
再次册毕旅进行测试,将后台的GetMapping修改为PostMapping,修改前端请求代码后重新发起请求进行测试
可以看到POST请求还是提示跨域请求,对应的错误信息则是 Access-Control-Allow-Headers ,也就是说请求头中包含了不被允许的信息,这里图省事儿用 * 通配符把所有请求头都放行
这样处理之后,请求就可以正常访问啦
路径占位参数,就是将参数作为请求路径的一部分,例如你现在正在看的这篇博客使用的就是路径占位传参
这种传参方法很简单,就不细讲了,可以效仿他这种方法写个测试案例
这里需要注意区分【路径占位传参】和【路径传参】两个概念,不要记混
什么是路径传参?发起一个请求 http://localhost:8080/index?a=1&b=2 ,在路径 ? 后面的都属于路径传参,路径传参就是将参数以明文方式拼接在请求地址后面
路径传参使用【正常接收参数】中的实例代码即可接收到值
除了自己手动拼接请求参数之外,axios在config中提供了params属性,也可以实现该功能
表单类型参数,就是通过form表单提交的参数,通常用在例如HTML、JSP页面的form标签上,但如果是前后端分离的话就不能使用form表单提交了,这里可以手动创建表单对象进行传值
需要注意,GET请求一般只用于路径传参,其他类型传参需要使用POST或其他类型的请求
表单类型参数也是【正常接收参数】中的实例代码接收值
小程序删除了FormData对象,不能发起表单类型参数的请求,如果非要写的话可以试着使用 wx.uploadFile 实现,这里就不尝试了
请求体传参,是在发起请求时将参数放在请求体中
表单类型参数需要使用上面【请求体接收参数】中的实例代码接收值
axios如果发起的为POST类型请求,默认会将参数放在请求体中,这里直接写即可
小程序代码也是一样的,当发起的时POST类型的请求时,默认会把参数放在请求体中
在实际开发中大概率不用写前端代码,只负责编写后台接口,但怎样才能知道前端请求是什么类型参数?
关于这点可以通过浏览器开发者工具的【网络】面板可以看出来,网络面板打开时会录制网页发起的所有请求
路径占位传参就不解释了,没啥好说的,这里介绍一下路径传参、表单传参和请求体传参
编写好路径传参的请求代码后切换到网络面板,点击发起请求:
编写好请求体传参的请求代码后切换到网络面板,点击发起请求:
编写好表单类型传参的请求代码后切换到网络面板,点击发起请求:
掌握了前后端交互的流程就可以正常开发网站了,这里推荐后端返回一套规定好的模板数据,否则某些情况可能会比较难处理,例如这个查询用户列表的接口:
该接口乍一看没毛病,拿到用户列表数据后返回给前端用于渲染,合情合理,可是如果后端业务逻辑有BUG可能会导致前端接收到的结果为空,这种情况下前端就需要判断,如果接收到的值为空,就提示请求出错,问题貌似已经解决,但是如果表中本来就没有任何数据的话有应该怎么处理
上述的就是最常见的一种比较头疼的情况,所以针对这种情况最好指定一套标准的返回模板进行处理
根据刚刚的举例来看,返回结果中应该有一个标识来判断该请求是否执行成功,如果执行失败的话还应该返回失败原因,响应给前端的数据会被转换为JSON数据,使用Map集合来返回最合适不过了
在后台接口编写完成后,一般情况下我们都需要进行测试,GET请求还好,浏览器直接就访问呢了,如果是POST请求还要去写前端代码就很烦,这里介绍一款接口调试工具ApiPost
你可能没听过ApiPost,但是你大概率听说过Postman,他们的用法几乎一致,且ApiPost是国人开发的免费的接口调试工具,界面中文很友好
这里也可以看出来,form表单传参其实也算在了请求体里面,只不过使用的是 multipart/form-data 类型的参数而已,而之前提到的请求体传参对应的就是 application/json
② ssm框架怎么一次保存多条数据(往数据库一次增加多条),前端怎么传参数到后端,后端怎么接收数组
将后端数据库的某个表连同其结构数据和数据重新分别导入所有的前端ACCESS数据库后再删除后端数据库那个表就好了。当然最快捷的方法是只对一个前端这么做然后再分发那个前端给各个终端用户。 记得导回后端表前先删除前端数据库对后端数据库那张表的链接(链接表)。
③ js前台页面与后台如何传参
实现前端和后端的参数传递,其实就是前端(页面)向服务器发起一个请求,在请求中附带了一些我们需要的参数。当服务器端接收到这个请求后,通过解析得要我们要传递的参数,这要就达到了我们的目的了。
举两个例子
java我们可以通过:
request.getParameter("xxxx");//xxxx表示参数名称来获取请求参数名称
C#我们可以通过:
GET请求参数用Request.QueryString,获取POST请求参数用Request.Form
下面讲下POST和GET请求的主要区别:
1、GET请求的数据会附在URL之后(就是 把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连。POST把提交的数据则放置在是HTTP包的包体中。
2、GET方式提交的数据最多只能是1024字节,理论上POST没有限制。
3、POST的安全性要比GET的安全性高。安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么 别人就可以拿到你的账号和密码了。
④ 前端ajax异步传值以及后端接收参数的几种方式
前台往后台传值呢,有很多种方式,大家听我细野猜细道来。
第一种呢,也是最简单的一种,通过get提交方式,将参数在链接中以问颂袭型号的形式进行传递。
后台往前台传值就要简单一些,单个数据或者封装数据可以直接使用return返回json数据给前台,如果是多个数据,可以使用```
PrintWriter进行传值,具体操作如下
非异步方式传值
非异步方式前台传递参数
1.与异步方式类似,使用form直接提交或者在链接中拼接参数即可。
2.后台接受参数方式不变,与异步方式完全相同。禅野
非异步方式后台向前台传递数据
⑤ 前端传递数据给后台的几种方式
1、通过表单传递
前端使用表单时,为name属性赋值,后台controller层方法的参数只要与name的值相同,即可获取到该属性的值。
2、ajax
js中将值取出来,通过data这个key传值,数据的值里面也是以key、value的方式,即JSON格式。
data: {key:value},
3、session域或request域
后台将值存入request域里面,使用request.getsession.setAttribute("名字","值")
前台使用sessionScope.名字取值即可。
⑥ 前后端分类,数据传输问题
目前我所知道的项目开发中,基本上都是前后端分离的。这就出现了数据传输的问题,前端传给服务器 或者 服务器传给前端的数据都是容易被别人窃取的。这里就要对传输的数据进行加解密,以保证数据安全。
下面介绍两种前后端数据传输的方式
前后端约定一个key,将请求参数按照字母排序拼接成一个字符串(通常都是ASCll排序),然后拼接上key,最后用MD5或者SHA进行加密,得到一个加密的签名sign,再把sign作为最后一个参数传到服务端。
服务端拿到前端传过来的结果之后,也将参数(排除sign)按照顺序拼接成一个字符串,再拼接上key,再用MD5或者SHA进行加密,也得到了一个新的sign,服务端比较这两个sign,如果相同就说明传回来的数据没有问题,如果不相同,说明数据被串改了。
例如:
传递的参数是
id=5&age=10
现在通过加签 应该传递的参数为
id=5&age=10&sign=MD5(age=10&id=5)
服务端拿到的就是
id=5&age=10&sign=MD5(age=10&id=5)
服务端经过筛选参数,得到 id=5&age=10 ,然后进行排序得到 age=10&id=5 ,再MD5得到sign,两个sign进行比较
目前我知道的根据秘钥的使用方法,可以将密码分为两种
在对称密码中,加密、解密时使用的是同一个密钥,我们常用的AES算法就是对称密码算法。具体AES算法大家自己网络就好了
但是通常使用对称密码时,就会有秘钥配送问题。
例:发送者A将使用对称密码加密过得信息发送给接收者B,只有将秘钥发送给接收者B,B才能进行解密,这里A发送秘钥给B的过程中,就容易被别人窃取秘钥,别人拿着秘钥也能进行解密。
如何解决秘钥配送问题
我知道的几种解决方法
公钥密码
公钥密码中,密钥分为加密密钥、解密密钥2种,它们并不是同一个密钥。
目前使用最广泛的公钥密码算法是RSA
加密密钥,一般是公开的,因此该密钥称为公钥(public key)
解密密钥,由消息接收者自己保管的,不能公开,因此也称为私钥(private key)
公钥和私钥是一 一对应的,是不能单独生成的,一对公钥和密钥统称为密钥对(key pair)
由公钥加密的密文,必须使用与该公钥对应的私钥才能解密
由私钥加密的密文,必须使用与该私钥对应的公钥才能解密
1.由消息的接收者,生成一对公钥、私钥
2.将公钥发给消息的发送者
3.消息的发送者使用公钥加密消息
混合密码系统
不能很好地解决密钥配送问题
加密解密速度比较慢
混合密码系统,是将对称密码和公钥密码的优势相结合的方法,解决了公钥密码速度慢的问题,并通过公钥密码解决了对称密码的密钥配送问题
会话密钥(session key)为本次通信随机生成的临时密钥,作为对称密码的密钥,用于加密信息,提高速度
发送出去的内容包括
前端A >>>>> 服务器端B
发送过程,加密过程
接收过程,解密过程
文章参考了 猿天地的再谈前后端API签名安全? 和李明杰的底层原理iOS签名机制
⑦ 前端与spring交互数据的处理和接收基础方式
query params就是最简单的问号传参方式,而spring接受参数方式有以下几种不需要额外第三方包。
前端传参:
后台接收:
统一资源定位符(又称URL)是一种资源命名或定位格式,用于指定或寻址资源。 URL在Web上非常流行,在Web上使用URL格式寻址或标识网站和Web资源。
2000年Roy Fielding博士在其博士论文中提出REST(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨重的SOAP,成为Web API的标准了。
RESTful作为目前最流行的 API 设计规范,一定有着它独有的魅力:强大、简介、易上手。
前端传参:
后台接收:
以前的form表单和formData是ajax2.0( XMLHttpRequest Level2)新提出的接口,利用FormData对象可以将form表单元素的name与value进行组合,实现表单数据的序列化。
而x- www.form-urlencoded 是post默认数据传输格式,跟Query Params传参方式一样。
前端传参:
后端接收:
前端传参:
后端接收:
前端传参:
后端接收:
前端传参:
ajax/axios传输json对象,适用于GET和POST请求,且此时contentType必须为application/x-www-form-urlencoded; charset=UTF-8,ajax会自动将json对象转化为&连接的key=value格式的数据。axios需要指定传参params,而GET请求就跟Query Params传参方式一样的,POST请求就放入post请求体中。
前端传参:
ajax/axios传输json字符串,是前端js把json对象字符串序列化到内存然后以http协议通过网络传输到后台,而spring使用网络套接字把传过来的序列化的json对象进行反序列化转换为java对象使用注解@RequestBoydy。而以前使用java原生HttpServlet 需要通过request.getInputStream()获取数据然后使用JSONObject来反序列化。
ajax需要自己转字符串,asios使用data传参会默认给转成json字符串
Servlet的框架是由两个Java包组成:javax.servlet和javax.servlet.http。 在javax.servlet包中定义了所有的Servlet类都必须实现或扩展的的通用接口和类,在javax.servlet.http包中定义了采用HTTP[通信协议]的HttpServlet类。spring也是基于Servlet的框架的
什么是序列化和反序列化
对象的序列化就是把对象转化成字节序列进行发送、存储,反序列化在接收和读取的时候把字节序列转化成对象。
前端传参:
后台接收:这是json字符串用对象接收,也可以使用Map等。springboot项目添加spring-boot-starter-web依赖,默认提供了Jackson用于解析json,da大部分人使用om.alibaba.fastjson
通过关键字段@RequestBody,标明这个对象接收json字符串,然后自己使用Gson、fastjson等自己解析转对象