今天继续Java Web相关的知识。我们知道,在一个网页中,如果要与用户进行交互,那么至少得允许用户将自己的输入提交到服务端。今天就介绍最原始,最基本的一种方法。这种方法就是使用 html 的 form 标签。
表单
form 标签,我们通常称之为表单,是一种 html 标签,它的作用就是把定义在它内部的用户数据上交给服务端。我们做一个例子,就知道了,我们修改一下上节课的index.jsp
访问它的话,就能看到这样的网页:
然后,我们随便输入点什么,点击提交,一定会得到404,因为我们通过设置这个表单的action,将提交重定向到login.jsp了。怎么处理这个提交,这节课,先不管。我想先介绍清楚,这个提交到底发生了什么。
HTTP报文
记住一条,客户端和服务端之间的通讯永远都只能是http协议,你可以扩展(例如某些云盘就是在一定程度上对协议进行扩展,再比如web service也是在http协议之上进行升级),但决不可能完全绕过HTTP协议。所以,要想成为一个好的web开发人员,分析http报文是一项基本功。
这里插一点,先声明,我对于培训班学习并没有什么偏见,培训班因为要速成,要快速地让学员做出一个网站来,把HTML,CSS,javascript,Spring,Hibernate,mybatis等等一股脑地推给学员,胡子眉毛一把抓,这样子的教学方法,不要说很多同学没有计算机基础,即便是有些Java基础的同学也很难这么快掌握。学技术要学关键点,比如html这个东西,做为后端要知道一点,但是在前后端分离的今天,学Java web开发,再去学习css和javascript就真的是难为大家了。所以,新手们在学习的时候,要学会舍,你要是学后端,那前端就先扔掉,你要是学前端,那后端就先扔掉。等把某一端搞清楚了,自然也就知道另外一端的功能了。Server 和 Client 不过就是通过 HTTP 协议把消息发来发去罢了。抓住这个主线,才能理解得深刻一些。否则的话,太容易陷入到各种细节中去。
吐槽回来,我们接着看,使用工具,例如tcpdump等抓包工具,把http报文打出来。我们看一下,先输入hello,然后在密码框里输入 world,再点击了“提交”以后,浏览器给服务端到底发了什么东西。
GET /login.jsp?username=hello&passwd=world HTTP/1.1
Host: localhost
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.18 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Referer: http://localhost/login.jsp
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8
我们看到,HTTP报文的第一行,还是标志了这个报文是一次GET操作,然后 username 这个输入框的内容 hello 已经被拼到地址栏里去了,而且在网页上显示为省略号的密码也被拼到地址栏里去了。做为HTTP报文中请求的URI资源一起发给服务端了。
从这个角度来讲,GET这种做法十分糟糕,因为我们的密码还会以明文的方式显示在地址栏里。
HTTP协议规定了很多种method,GET只是其中之一。实际上 form 可以使用另外一种HTTP的method,那就是post,我们把form的method属性改为post,然后再看一下HTTP报文。
... 相应地,我们可以看到现在的报文就不一样了:POST /login.jsp HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 27
Cache-Control: max-age=0
Origin: http://localhost
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.18Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Referer: http://localhost/login.jsp
Accept-Encoding: gzip,deflate,br
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=node01mgibwcqifx8cpi5bjl95rhac0.node0
username=hello&passwd=world
这其中,content-length是值得注意的。它描述的是HTTP报文的正文内容的长度。使用post方法,第一行,http method会发生变化,然后我们自己的参数都会以正文的形式发送到服务端。而不再是直接放在URL里,展示在地址栏里了。
从这个角度讲,post 比 get 的安全性要稍微好一点,但其实好不到哪里去,密码仍然是以明文形式在网络上发送。如何彻底解决安全性问题,我们后面再说。现在先不管。
JSP处理用户参数
不管怎么说,用户参数是通过HTTP协议发到服务端了。我们拿到这个参数以后,要去数据库里查询,看看密码是不是能匹配上,如果匹配上,就登陆成功了,如果匹配不上,就要给出错误提示。
好,既然我们要请求的网页是login.jsp,我们就在上节课所说的jetty工程下新建一个login.jsp,然后在里面输入:
<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%@ page import=“java.io.,java.util.” %>
<table>
<tr>
<td>用户名:</td>
<td><%=request.getParameter("username")%></td>
</tr>
<tr>
<td>密码:</td>
<td><%=request.getParameter("passwd")%></td>
</tr>
</table>
然后再重新运行一下首页,就可以看到:
上面的例子中,Jetty在帮我们分析完http报文以后,都把这些用户参数放到一个叫request的内置变量中去了。request变量不需要声明,是JSP内嵌的对象,它的作用就是封装用户数据,换句话说,Jetty从HTTP报文中得到的参数都以某种形式存在这个request中。
实际上,request这个内嵌变量是JSP标准规定的。但是具体怎么实现,可能各种Server都不一样。这一点,涉及到Java标准的制定,这些知识我们下节再讲。
好了,今天总结一下,要掌握的重点就是一个:浏览器通过form获取用户参数,并把它们转化成HTTP报文发给服务端,服务端从报文中解析出参数,然后就可以在服务端脚本中加以使用了。
还有就是这我总结出了一些架构视频资料和互联网公司java程序员面试涉及到的绝大部分面试题和答案做成了文档和架构视频资料还有完整高清的java进阶架构学习思维导图免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
料领取方式:加群:374308445填写【CSDN 资料】即可免费获取!!!
如果您喜欢本文章,可以点击关注,每天将有更多精彩文章与您分享!