Servlet与HTTP介绍学习
http介绍:http是一套规范,一种网络数据交互的标准协议,不同的语言,不同的数据想要实现合理的数据交互(例如:浏览器和服务器数据交互),就得按照他所规定的协议来,这样就会形成标准的(大家都认识的)数据交互。
http交互流程:
1.客户端和服务器建立起连接通道。
2.客户端发送请求给服务器。
3.服务器处理请求后将结果响应给客户端。
4.客户端和服务器的连接通道关闭。http1.1会等待一段时间如果没有请求进来就会关闭。
特点:
1.数据结构:他是以键值对的形式描述数据结构的。
2.无连接:一次请求一次响应,当本次请求得到响应时即本次数据交互结束(客户端和服务器断开连接)。在http1.1中请求处理完成响应后,客户端和服务器不会立即断开连接而是在等待一定时间后再断开,如果等待期间有请求过来那么等待时间会重新开始(延长)。
3.无状态:第一次请求处理完成后,要发送第二次请求,但即使两次请求用的是相同的数据,在http中也是没有任何关系的,所以二次请求任然需要重复第一次的流程,http他是没有记忆功能的,所以哪怕两次请求一模一样,各自的请求还是要发送全部的请求数据,这就是无状态。
4.http是基于tcp协议发送数据的,所谓tcp大概意思为:即两端连通以后再进行数据请求和数据响应。udp:即连接和请求一起发送过去,不会等到双方连接通畅之后再进行,所以udp协议不会保证数据一定发送到另一端,但效率比tcp要快。
http请求格式:
1.请求头内容: 请求方式(get、post...) 请求地址(https://i.cnblogs.com/editposts.aspx?opt=1) http协议(1.0/1.1)
2.请求行、消息报头:这里面规范了服务器需要额外信息,一般浏览器会自动封装,如:能解析的数据格式等,客户端需要的cookie数据。
3.空行
4.请求数据
在实际请求中浏览器为了方便展示观看:会将上面请求格式中的内容给分开展示,像get请求会将请求数据带到请求地址后面。
http响应格式:
1.响应行:http版本 状态码 状态消息
2.响应头:消息报头:服务器和浏览器之间的额外数据,例如:本次响应的消息类型...等等。
3.空行
4.响应实体:具体响应的数据。
额外解释:
1.消息报头:消息报头中的信息和请求头响应头中的信息,这些信息中主要说明本次数据交互所采的各个属性:例如本次数据的格式:xml/json...这些数据都是服务器和浏览器自动处理的不需要开发者关心,开发者只管将自己需要的数据添加进去即可:例如cookie,服务器中对这些常用配置已经做了处理,而浏览器的各个厂商也对浏览器做了处理,所以程序员只需要关心请求数据和响应数据即可。
上面对http的大概介绍就这么多,下面主要介绍servlet:
客户端向浏览器请求的流程:前端网页源码 -> 浏览器请求封装(主要是消息报头以及版本信息等) -> 服务器处理 -> 根据请求的不同(get post...) -> 分配到后端相应的接口逻辑中
servlet的请求流程: 网页请求 -> 服务器收到请求后寻找对应的servlet -> 然后将请求信息以及要响应的信息封装成request response对象传入响应的servlet对象的service方法中去调用此方法。
好了,说了这么多,开始上代码:
web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="webapp_id" version="2.5"> <!--配置servlet --> <!--配置servlet类路径 --> <servlet> <servlet-name>my</servlet-name> <servlet-class>cn.mr.li.myservlet</servlet-class> </servlet> <!--配置访问方式 --> <servlet-mapping> <servlet-name>my</servlet-name> <url-pattern>/my</url-pattern> </servlet-mapping> </web-app>
servlet:
1.request作用域:一次请求一个数据作用域仅限本次请求所用到逻辑范围,但通过请求转发的方式可实现多个servlet之间数据共享,一次请求,一次响应。
2.cookie:客户端数据存储技术,并用于请求自动携带,至于带什么,请求哪些路径时带,生命周期等都是服务器设置的。然后由response对象通知客户端去执行具体的操作。
3.重定向:response.sendredirfect(uri),只能防止重复刷新重复请求,但是不能数据共享,如果将所有数据都放在cookie中将不安全,而且也无法验证当前cookie就是此人。
4.session作用域:同一个对象请求多次数据共享。
5.sessioncontext作用域:不同对象请求多次数据共享。
6.tomcat服务器下的web.xml文件中的全局变量将是所有服务器都共享的数据范围。
package cn.mr.li;
import java.io.ioexception; import javax.servlet.servletconfig; import javax.servlet.servletcontext; import javax.servlet.servletexception; import javax.servlet.http.cookie; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpsession; public class myservlet extends httpservlet{ private static final long serialversionuid = 8834328433966095720l; @override public void service(httpservletrequest request, httpservletresponse response ) throws servletexception, ioexception { //编码,从iso8859-1编码后再转换成utf-8,uname字符串是请求的变量名 string uname = new string(request.getparameter("uname").getbytes("iso8859-1"), "utf-8"); //新建cookie:将cookie放到客户端的消息报头中 cookie cookie = new cookie("id", uname); //此cookie的最大生命周期,设置了客户端就会存到他自己的硬盘中,生命周期一到就会删除,默认有效期期是本次会话,会话一旦关闭则失效 cookie.setmaxage(24 * 3600); //往响应中添加cookie,这样才会通知到客户端下次请求会带上本次存放的数据 response.addcookie(cookie); //设置访问哪些路径、目录先时可以带cookie cookie.setpath("/端口号后的链接"); /** 请求转发 一次访问 后端逻辑跑多个servlet, 记得要加return*/ //给requset添加自定义属性 request.setattribute("key", "value:给下个流程的参数,此值是本流程产生的,这里是可以放一个object对象的"); //演示请求转发,意思是本servlet处理完了本此servlet管理的业务,将自动转向下一个servlet处理后序流程(原子性), //但如果客户端网页一刷新就重新开始一次请求,如果是转钱业务用请求转发就完犊子了,他会转了因为页面刷新再次请求又会转,所以还是要看具体业务的。 request.getrequestdispatcher("其他sevlet的别名url-pattern标签中的").forward(request, response); /** 重定向 多次访问 头端通知前端,此时前端会自动访问多个servlet, * 但是request中如果有属性值得话request.setattribute,就无法在下次请求中带了,因为是不同的requset对象,不过session可以解决*/ //因为请求转发用户一但刷新页面将会不安全,会重复跑流程,所以有了重定向, //相当于本次servlet处理业务完成后直接通知客户端访问下个servlet此时客户端会自动访问下个servlet response.sendredirect("直接传下次要访问的uri"); /** session 一个request在服务器上的对象,一个很全的对象,例如:某个用户访问了服务器:服务器将此用户的user信息 * 查询出来放到session中,那么此用户下次请求servlet是甚至只传很少的参数即可 */ //创建session此方法会从requset的cookie中取出他自己的sessionid,如果没有或者没取到则会创建一个新的session对象 //并且将sessionid重新放到cookie中,默认sessionid的生命周期30分钟,一旦断开连接则会销毁 httpsession session = request.getsession();//此session是用请求对象的sessionid取出来的。 //给session对象赋值属性值 session.setattribute("key", "object类型"); //设置session的生命周期,时间单位:秒 session.setmaxinactiveinterval(123); //强制让session过期 session.invalidate(); /** servletcontext对象:此对象的数据整个服务器共享,也就是说存放在此对象中的数据整个服务器上都能拿到,前提是要能得到此对象 */ servletcontext sc1 = this.getservletcontext();//方式1 sc1 = this.getservletconfig().getservletcontext();//方式2 sc1 = request.getservletcontext();//方式3 //同样赋值 sc1.setattribute("key", "objcet"); //获取全局配置web.xml sc1.getinitparameter("hahhahah"); //获取全局配置的所有key名 sc1.getinitparameternames(); /**servletconfig专门读取某个servlet下的配置的,有次方法后所有的key都将不需要硬编码*/ servletconfig config = this.getservletconfig(); //读取servlet专属变量名 string value = config.getinitparameter("key");//web.xml init-param标签中 //给浏览器打印文本 response.getwriter().write("hello world!!!"); } // @override // protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception { // resp.getwriter().write("do get!!!"); // } // // @override // protected void dopost(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception { // resp.getwriter().write("do post!!!"); // } // // @override // protected void doput(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception { // resp.getwriter().write("do put!!!"); // } }
顺带提一下jsp:jsp的原理就是讲html文件中的所有代码全部读进servlet中转为输出语句打印到控制台上,而其中的java代码,会读过来后执行响应的逻辑后再自己的位置打印到浏览器。