开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:Ajax & JSON 2】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15763
Ajax & JSON 2
内容介绍
一、 举例说明
二、 使用 React 开发前端
一、举例说明
有关问题能不能传数组;所写的不为 OR 映射, OR 映射应当如何,例子中 reactdb 就是 Ajax 与后端进行交互的例子后段,这个例子中,首先,后端是从数据库里面抽象表示 Book ,运用了 Entity 进行抽象在映射 Book 这张表;在 servlet 中,使用 Hibernate 获取所有的书,在使用 json 数组将书遍历一遍后全部放入 json 数组里,随后将 JSONArray 转换成 JSONString ,于是将 JSONString 返回,所需记住无论表示一个对象或一组对象的概念,最终就是一个 booksString ,传数组是以 Json 数组的方式进行传递,原因是在前端是 JS ,在后端是 Java ,不可以将 Java 的数组返回,只能传纯文本的内容,文本的内容是表达 Json 字符串,此字符串本身可以表达一个数组,所以刚刚所提例子后台和前台交互时就是书的列表中所有书拿到前台,传输的为 book 的一组对象,只不过是纯文本表示的 JSON 对象,不能够传原生的 Java 对象,要将它转换成 JSON 格式, JSON 本质是一个 Key Value , Value 本身也可以作为数组,这样处理后前后端就可以完成传数组。
1.数据库的访问
如图,当接收到前端请求之后,无论怎样从数据库中接收到,将这段代码改写成 Hibernate 或 String 都在使用 OR 映射,都是用 Hibernante 在后台中将数据拿出,组成了一个返回给客户端的字符串将其写回前端,前端与后端只是在请求层面上的交互,后端怎么拿到数据以及怎样将其组装成一个字符串,前端与后端都无关系,不存在耦合的关系,发起请求,后端得到一个响应,后端使用什么方式得到取决于自身设计,不是说使用 Ajax 后端就无法使用 OR 映射,所给出的例子使用的就为 OR 映射。
接下来讲解案件是如何得到的,在输入的 input 的文本框里增加了一个按键为弹起的事件,当按下一个按键松手将它弹起会发送 showHint ( this value )这样的请求,如图
ShowHint ( str )创建一个 Ajax 请求,向 Hint ?q =” str 发送请求, readystatechange 本身指事件,指 xmlhttp 是一个请求,一旦发送浏览器会监听它的状态变化,状态只要发生变化例如正在处理或返回,就会触发此事件,而已经注册了只要发生变化就需要调用函数,所以一旦有按键按下并弹起时, Hint ?q =” str 此函数会发送请求, listvalue 是在输入框内输入的东西,它会将其当作 Hint 位置上的 q 参数发送到后台,返回之后找到 txtHint ,将它的内容替换成返回的结果,发现一旦输入东西就会不断发生变化,只要存在按键弹起就会调用函数,后台响应 Hint 的与前台形成对比。
Hintservlet 的处理也需要获取 response 上的 writer,没有在数据库中再次操作,做了30个元素的 String ,在请求中将用户输入的信息当做参数 q 发送,将参数 q 取出观察 q 里是否输入,比如输入但是已经删除,就不能做任何的提示,判断是否大于0,大于0的情况下,会遍历所有的元素,观察有无包含 q 的内容; indexOf 是指使用 q 的字符串到 a [ i ] 的字符串里寻找作为子字符串出现的 String ,若大于0则存在,若不存在则会返回-1,大于等于0说明30个元素中某一些包含 q ,就可以将其作为提示,首先判断提示是否为空,若为空则为 hint = a [ i ];若不为空说明已经放入,则为 hint = hint + “,”+ a [ i ],此时 hint 的内容就已经完成组装,组装完成再去判断 hint 是否为空;存在最开始 hint 为空的可能,本来不为大于0,中间部分并未执行,所以为空;也存在遍历完成后全部小于-1的可能性,总之, hint 为空则无建议,不为空就将 hint 返回,这就是 hint 的实践逻辑。
真正的代码里,在页面稍微加一点内容,代码与最初相同,发送请求,在 text input 里,只要按键弹起,就调用函数,图中 this . value , this 指当前的 text 对象, value 指填进去的内容,后端的 Hintservlet 的逻辑就如上展示。如需更加完善,名字不是硬编码写入而是从数据库中读出。
如图,输入 a , b ,如将其全部删除,就不显示。输入具体人物“曹操”,在30个元素中就不存在,查询后明确数据库中存在,将其替换,如何加提示信息,从例子中可以得到代码 Servlet 如图,
相同的地方是无论为上图哪一种,不是一个完整的html 页面,是一个具体的数据。
在输入时,存在按键按下并弹起就会调用,但是在调用时并没有固定,交互的过程不断有输出,一直在发送请求,等待返回的过程中也一直在接受请求并进行处理,这样的方式前端不需要做处理可以继续的操作。输入具体人物“刘备”,当点击查询后,更新了 username : Liubei role : BIGBROTHER ,不会出现页面完整刷成白色再出来的过程,如同所讲解过的 react 相同,只刷新了状态中变化的部分。
3.
如图,例子在 ShowUser 中, shouUsers ( str )代码需要存在一个参数,参数在后端有下拉选择框,当改变里边的内容时就会调用 showUsers ( this . value )函数,此函数传进去的参数是当前选择框中选中的哪一个, Admin 、 DBA 、 Guest 、 VIP 、 Tester 、 Developer 当中的某一个会被当成参数传递给 showUsers ,拿到之后如图
如这一段拿到,在选项中没有选择,就没有任何提示,上图代码已经熟悉,当返回之后将响应的文本替换掉显示提示信息的地方,接下来发送请求,向 ListUsers 中发送,带参数 q ,如有状态返回就调用函数。
4.
后台为 ListUsers ,前面的代码都是类似的,取结果获取数据库连接,在 user 表中寻找 username 等于参数,参数就是前端发送的参数,也就是 Admin 、 DBA 、 Guest 、 VIP 、 Tester 、 Developer 中某一个,取到之后执行查询,查询出的结果可能不止一个,如果结果为0,表示不存在这样的用户;如果不为0,则输入了上图的结果,是一个表格,与前边不同的是它是一个局部的 xml ,为了使输入方便观看,在真正执行过程当中不会传此信息,只会传所讲的数据,如何制成表格是发送到前端使前端做,此时前端比较简单,所以在后端组了一个表格将用户名、密码、邮箱取出。如下图的脚本就与讲解过的相同。
它依然使在访问 Ajax 数据库,
当没有操作时,显示的为上图的信息,如换成 DBA ,则如下图显示,
此例子讲解了前后台交互来显示用户。以上的例子包括如何获取用户、如何获取信息,总的来看,后端唯一的变化是 Servlet 向 response 写东西时不是写完整的页面,而是写局部的数据;而前端的变化是发送 Ajax 的请求,拿到数据后不会刷新整个页面,而是刷新状态变化的部分,这是前后台所发生的变化,现在所有的代码都是原生代码需要自己写。
5.
接下来讲解一个常用但是在此项目中不常用的,比如 jQuery 将所有的代码封装,复杂的屏蔽,它提供了 Ajax 的方法供使用,还可以进行细分,可以有 get 、 post 、getScript 、 getJSON 方法,因为存在 jQuery 的框架,所以使用的版本影响不大,在整个页面被加载时,执行一个动作,动作就是定义一个函数,存在 btn1 按钮,此按钮被点击时,应执行如图所示的动作,对 test 标签内的内容替换成 resources / poem . txt ,此内容在应用的更目录上 http :// loadhost /:8080/ resources / poem . txt ,对照其发送请求,请求已经有几件事情被封装不用指定,首先是 get 方法,其次是异步,不需要同步,所以代码写起来比较简单,代码的例子如下图所示,
版本在不断提高,在组装外部端代码中,所有的 js 在一个目录里直接进行引用就可以,resource 存在于 webapp 中,也可以在项目结构中直接指定哪一个目录是 resource ,在遍历中就会打入到 webapp 中,方法不唯一。页面的效果,会出现一个按钮,
点击按钮,就会将上图文本的内容获取后将其替换,过程是以异步调用的方式执行。
存在 get 、 post 两种方法如何使用,如,此时存在 button ,当 button 被按下时需要执行一个函数,为 Ajax 的概率,对照 resources / poem . txt ”发送请求后调用函数,其中 data 为响应回来的结果(相当于 responsetext ), status 为响应回来的状态,(相当于 state ),随后使用弹出框的方式显示,内容是什么,状态是什么,得到如下图的效果。
6.
写法不同因为里面可以带参数,同样对照 JQuery 发送请求,使用 alert 方式来显示返回的数据和状态,参数如何使用,后台存在 WebServlet 做处理进行监听,在 response 中写信息, name 属性生活在指定参数生活的城市,所以通过 Parameter 传递了 name 与 city ,此时后台拿请求中的 name 属性和 city 属性。这就是使用 JQuery 来描述。
二、 React 开发前端
使用 React 开发前端, React 是如何访问后台拿到数据后将其替换掉,后台为 Hibernate 映射, Servlet 在接收前端 BookManager 请求后在数据库中寻找所有的 book ,随后将所有的 book 以 JSON 的方式返回,它的前端是在创建外部应用时默认的前端,不是所需要的前端,前端实际是写在一个项目中,项目与之前唯一的区别是,之前的项目 data 中有内容,现在数组为空,这才是真正需要访问的前端,点击 Get Books 按钮,后台将书返回,得到了如下图的数据,
如图数据为在数据库中写进去的数据,数据库如下图所示,
在数据库中添加了中文“曹雪芹”,将其传递到前端正确显示“曹雪芹”,不允许存在乱码。在此例子中,需要讲解前后端如何交互、在交互时需要解决的问题是跨域以及中文如何处理。
例子中前端的数据 data 为空,在此处增加了一个按钮 Get Books ,点击之后需要调用 Get Books 函数,函数与其他按钮的写法相同,使用 fetch 抓取数据,对照“ http :// localhost :8080/ se 122_10_ reactdb _ war / BookManager “发送请求,后端的代码 Servlet 位置,在应用运行起来后在相应位置等待请求, response 中存在 JSON 对象, JSON 中包含一组书,所以在返回的结果上将 then 函数调用,在调用 then data 就得到了里面的 JSON 数据,用 set 方法将当前的 data state 设置成已经返回的 data ,由于使用 setState ,会触发页面做 render 这个动作,重绘时 data 里已经存在内容,所以就将书画出来。前后端的交互就是前端增加了一个函数和一个按钮,后端存在 Book . java , Entity 是映射实体类,它映射到 book 这张表中, book 中会按照表格中的内容存在名字、作者、语言、发行年代以及销量,上图中存在此信息。 Servlet 在 doGet 时获取当前会话对象,将所有书全部拿出,不断的迭代,每次迭代得到 book 类型的对象,使用 JSON 方式处理,先组装 ArrayList ,将 book 中的 Title 、Author 、 Language 、 Published 以及 Sales 全部放入 ArrayList 中,将 ArrayList 转成 JSON 对象添加到 booksJson 中, Json 对象再通过 JSON . to JSONString 转成字符串,直接的 JSON 用 out 转成字符串就将其写出,写出后就会得到响应,而此处通过 Hibernate 处理,全部处理完成后将 Transaction 提交,这就是后台写 Servlet 。
JSON 如何处理上图所示代码,写法不代表唯一写法,如用其他 JSON ,则 API 不为上示。
如存在 Java 对象,使用 RestController 在返回时直接将其转成 JSON ,更加直接简单。
Annotation 不是一定义就被使用,是不同的框架有不同的批注解释,比如 Spring 、 Hibernate 、 Struts 、 Mongoldb 存在本身的 Annotation ,使用哪个就是哪个框架中的定义,不存在标准且都遵循的 Annotation ,因为 Annotation 实际是遍历完代码后框架对 Annotation 做一些动作。
这是后台的代码,在真正运行时会出现乱码,比如《小王子》作者处是法文词,如果不做任何处理,就会出现乱码,在 response . setContentType 中字符集是需要使用 UTF -8;如使用 fastjson ,在调用 JSON . toJSONString 时要调用参数,这样就保证不出乱码。
更重要的是,此代码到此为止在访问的过程中会出现错误,错误是因为违反了同源策略,同源策略指有关外部安全性导致的问题,解放方案是在 BookServletManager 、 response . setHeader 中写入允许谁访问,写进去前端应用客户端在 localhost 3000,也就是说对于此源是允许访问;在 http 协议里,是跨域的资源共享,缩写为 CORS ,它存在安全问题,需要做控制,特别是使用 XMLHttpRequest 和 Fetch API 做请求时,在抓取数据时对跨域的访问具有约束作用。
何为跨域访问,如, http :// domain - a . com 是一个域名,要使用 domain - b . com 的过程就叫跨域,两者域名不相同。
举例说明,当开发了一个完整的系统,页面来自于 domain - a . com ,页面就会获取 domain - a . com 里的某一张图片,域名是相同的,访问也就不存在问题,但是当引用另外网站的图片或字体时,它来自于 domain - b . com ,此时就需要受控制,不一定能够获取到,因为域名不相同,都属于本地为何会不相同,首先,源是由协议名、端口名以及主机名共同定义的,比如前端是3000端口,后端是8080端口,就不能进行访问,因为它们属于不同的端口。