Java Web
JSP和Servlet区别
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
Servlet不同版本区别
- 2.3版本:web-app里的标签有一定的顺序
- 2.4版本:多个url不能映射到同一个servlet
- 2.5版本:解决多个url不能映射到同一个servlet的问题。
- 3.0版本:web.xml配置文件中包含: 默认页配置、session超时配置和错误提示页配置。
JSP内置对象
JSP有9个内置对象:
- request:封装客户端的请求,其中包含来自GET或POST请求的参数;
- response:封装服务器对客户端的响应;
- session:封装用户会话的对象;
- out:输出服务器响应的输出流对象;
- page:JSP页面本身(相当于Java程序中的this);
- pageContext:代表页面上下文,该对象主要用于访问JSP之间的共享数据;
- exception:封装页面抛出异常的对象。
- application:封装服务器运行环境的对象;
- config:Web应用的配置对象;
JSP基本动作
JSP 共有以下6种基本动作
- jsp:include:在页面被请求的时候引入一个文件。
- jsp:forward:把请求转到一个新的页面。
- jsp:setProperty:设置JavaBean的属性。
- jsp:getProperty:输出某个JavaBean的属性。
- jsp:useBean:寻找或者实例化一个JavaBean。
- jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。
过滤器的作用
Java Web开发中的过滤器(filter)是从Servlet 2.3规范开始增加的功能,并在Servlet 2.4规范中得到增强。对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。
在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,在过滤器中你可以对响应的内容进行转换,然后再将响应发送到客户端。
常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图像格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等。和过滤器相关的接口主要有:Filter、FilterConfig和FilterChain。
forward与redirect区别
- 从地址栏显示来说
- forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器。浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址。
- redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的URL。
- 从数据共享来说
- forward:转发页面和转发到的页面可以共享request里面的数据。
- redirect:不能共享数据。
- 从运用地方来说
- forward:一般用于用户登陆的时候,根据角色转发到相应的模块。
- redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等。
- 从效率来说
- forward:高
- redirect:低
标签库的好处
- 分离JSP页面的内容和逻辑,简化了Web开发;
- 开发者可以创建自定义标签来封装业务逻辑和显示逻辑;
- 标签具有很好的可移植性、可维护性和可重用性;
- 避免了对Scriptlet(小脚本)的使用
get和post请求
- Get和Post的区别:
- get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
- get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用"?"连接,而各个变量之间使用"&"连接;post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指向URL;
- get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据,上传文件通常要使用post方式;
- 使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
- post能发送更多的数据类型(get只能发送ASCII字符)
- post比get慢
- post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作
- 为什么get比post更快?
- post请求包含更多的请求头
- post在真正发送数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据
- get会将数据缓存起来,而post不会
- post不能进行管道化传输
- post请求的过程:
- 浏览器请求tcp连接(第一次握手)
- 服务器答应进行tcp连接(第二次握手)
- 浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
- 服务器返回100 Continue响应
- 浏览器发送数据
- 服务器返回200 OK响应
- get请求的过程:
- 浏览器请求tcp连接(第一次握手)
- 服务器答应进行tcp连接(第二次握手)
- 浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
- 服务器返回200OK响应
也就是说,目测get的总耗是post的2/3左右。
- get传参最大长度的理解误区
- http协议并未规定get和post的长度限制
- get的最大长度限制是因为浏览器和web服务器限制了URL的长度
- 不同的浏览器和web服务器,限制的最大长度不一样。要支持IE,则最大长度为2083byte,若支持Chrome,则最大长度8182byte;
- 服务器Apache能接受url长度限制为8192 字符;Microsoft Internet Information Server(IIS)能接受url长度限制为16384个字符。这个是可以修改的(IIS7)
支付接口调用两次,如何防止重复扣款?
- 保证幂等性主要是三点:
- 对于每个请求必须有一个唯一的标识,举个例子:订单支付请求,肯定得包含订单 id,一个订单 id 最多支付一次。
- 每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录状态,比如支付之前记录一条这个订单的支付流水。
- 每次接收请求需要进行判断,判断之前是否处理过。比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId 已经存在了,唯一键约束生效,报错插入不进去的。也就不用再扣款了。
- 实际运作:
- 实际运作过程中,结合自己的业务可以利用 redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。
- 要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键 unique key。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 redis 里面去,set order_id payed,下一次重复请求过来了,先查 redis 的 order_id 对应的 value,如果是 payed 就说明已经支付过了。
cookie 和 session 的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE,并进行COOKIE欺骗。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
如何保证cookie的安全性?
- Cookie 依然遵循"同源策略",只有用目标服务器域名设置的 Cookie 才会上传,而且使用 document.cookie 也无法读取目标服务器域名下的 Cookie。所以不能跨域获取cookie数据
- cookie存储在客户端,session存储在服务器端,服务器端有个明细列表,将cookie数据与列表一一对应。
- 服务器传送cookie时设置属性secure为true,表示创建的cookie只能在HTTPS连接中,被浏览器传递到服务器端进行会话验证,如果是HTTP连接则不会传递该信息,所以很难被窃听到。
- 服务器传送cookie时设置属性HttpOnly,HttpOnly告知浏览器不允许通过脚本document.cookie去更改这个cookie值,事实上,设置HttpOnly之后,这个值在document.cookie中不可见。但是在HTTP请求的过程中,依然会发送这个Cookie到服务器端。
浙公网安备 33010602011771号