Servlet的介绍:
学习Servlet,就要了解什么是Servlet,在这里,向大家解释一下,Servlet其实是sun公司提供的动态web编程语言,用来开发动态web的,说白了,也就是一种java小程序,可以放到Servlet容器中来执行。
什么是Servlet容器?简单的来说,就是用于开发Servlet的容器就是Servlet容器 ,由此我们可以联想到web容器这个概念,同样的理解,用于开发web的容器叫做web容器,靠,是不是等于没说,反正我的理解就是这样的,这里的Servlet容器和web容器,现阶段,我都用tomcat,因为这个不收费,而且用于学习很好,以后工作用商业化的另说啊。
怎么运行Servlet呢?和当初学习java,写代码一样,这个时候,你可以打开记事本,写一个类,不过这个类要继承Servlet类,因为你马上要放到tomcat当中让其运行,而tomcat里面定义了一些规范,必须要是继承Servlet的类才能运行,所以你这个类要继承Servlet。写好了类还不够,然后你就要编译,运行,这里值得是打包编译,dos命令行可以写
javac -d . 类名(前提是你的classpath必须要有Servlet这个包),紧接着,把这个编译好的com包放到tomcat/webapps/应用名/WEB-INF/classes里面,这个时候一个简单的Servlet就可以运行了,浏览器运行吧
注意点:记事本写的时候,可以继承GenericServlet,但是用ide写的话,会自动帮你实现继承HttpServlet,这两个类有什么区别,关系就是父子,前者是后者的爸爸,因为我们的根类Servlet是一个接口,里面提供了实现他必须继承的5个方法,包括init(),service(),destroy()等等,而我们并不需要除了service()之外的方法,而这个时候GenericServlet刚好帮我们实现了除service()之外的其他4个方法,比较好用。令人更惊喜的是,这个httpServlet在GenericServlet的基础上又对service()做了一些强化,去掉不用的请求方法,所以现在看到的继承都是继承HttpServlet了。
Servlet的调用过程:
初步了解了Servlet之后,下面就要详细了解他的调用过程了。平时我们访问网页的话,会在地址栏敲下一段URL请求路径,也就是说的网址,例如http://www.baidu.com(百度主页其实是缺省web应用,缺省资源名),而完整的路径是由http请求协议+主机名+端口号+web应用名称+资源名称+具体参数,当你敲下这个路径时候,访问过程是这样的:
1.浏览器会到本机C盘里面的hosts文件解析你的主机名,如果没有就让dns域名解析系统帮你解析主机名,最后解析完毕,提交到相对应的服务器。
2.找到了响应的服务器,就要找你想要访问的web应用名称,服务器会解析请求行,找到你要访问的web应用。
3.找到访问的web应用,服务器会再解析请求行,找到你想要访问的具体web资源。
4.web资源你也找到了,这个时候就回到服务器下面的web.xml里面找这个具体资源的虚拟路径,找到了之后,再帮你找到服务器里面相对应的servlet。这个servlet是服务器创建的,同时调用init()方法做一些初始化工作,这个servlet会一直驻留在内存用,用于对后续访问的响应,直到你web应用被移除容器才会被销毁,这个时候调用destroy()方法,而service()方法用于做一些具体响应的操作。
5.servlet你都找到了,服务器会把servlet里面的响应组织成http响应发送给浏览器,然后浏览器用于显示到页面。这个过程就是浏览器和服务器之间的具体访问。
注意点:浏览器和服务器之间只是单纯的http请求关系。
Servlet的注意事项:
1.一个Servlet可以对应多个虚拟路径。 ---自己感受
2.虚拟路径可以用*好来表示。 ----自己感受
3.缺省Servlet(重点)---只要你给servlet的虚拟路径设置为"/",那么这个servlet就是缺省servlet一般缺省Servlet用于处理其他servlet都不处理的操作,通常呢,系统会有默认的缺省servlet,这个servlet会帮你访问服务器下面的500,404,静态页面等,而如果你自己设置了缺省的servlet,那么你就完了,你很有可能覆盖了服务器的缺省servlet,这个时候你不仅静态页面都访问不到,连报错页面都看不到。。。哎
4servlet的线程安全问题
这个问题也是一大难点,我们想想看,当浏览器访问服务器的时候,我服务器会创建一个servlet驻留在内存中,不过只有一个servlet,后续如果我在访问的时候,我开100个浏览器并发访问同一个servlet资源,那我擦,这个线程安全成了大头,你的浏览器要疯了,这个时候有三种解决办法
**加线程锁(synchronized)不过有个坏处,效率太低
**继承SingleThreadModel(原理不想说,基本用不到)也不能很好的控制线程安全,已经被废弃
**sun公司建议,还是尽量少使用静态变量,如果实在要用的话,还是加锁吧。
ServletConfig对象:
其实就是代表当前servlet在web.xml里面的配置信息,有四个主要方法
String getServletName()-----获得当前servlet的名字
Object getInitParameter(String name) ---获得当前web.xml配置的参数值
Enumeration getInitParameterNames()---获得当前web.xml配置的参数键的枚举集合
ServletContext getServletContext()-----获得当前web应用
ServletContext对象:
其实就是代表当前整个web应用,是javaweb四大作用域当中最大的一个作用域
只要是作用域我们就必须想到三个特征:生命周期、作用范围、作用
生命周期:服务器开启的时候,ServletContext对象会被创建,一直驻留在内存中,知道web应用被移除出容器或者服务器被关闭时候,ServletContext才会被服务器销毁
作用范围:在整个web应用内都有效
作用: 1.共享数据(只要是域,都有这个作用),在看的到的范围可以共享数据,通过setAttribute(),getAttribute(),remoteAttribute()这三个方法实现
2.获得初始化参数的值
通过getInitParameter()等方法可以实现
3.请求转发(一次请求,一次转发)
通过this.getServletContext().getRequestDispatcher(路径).forward(request,response)来实现
4.获取配置文件
this.getServletContext().getRealPath()用这个获得当前web资源的路径更准确
Response对象---其实就是一个接口
ServletResponse---Response对象的接口,提供了一些响应的基本方法
HttpResponse---用的最多的类,在ServletResponse的基础上增加了一些http的方法,做了强化
作为被服务器创建出来的对象之一---Response,他的作用还是不少的
作用1:用于向浏览器输出一句话,这里要注意乱码的问题,主要就看解码和编码是否一致,然后做出响应的处理
作用2:实现文件的下载,通过setHeader("Content-Disposition","attachment;filename=1.png");这个作用注意附件的名字如果是中文的话,就说明响应头里面包含了中文,是不可以的,要通过url编码也就是百分比编码URLEncoder.encode(string,"utf-8")来解决。
作用3:实现页面的刷新(注册成功,三秒钟回到主页)
setHeader("refresh","3;url=")和请求重定向有点像,不过通常在html里面写的多,
标签模拟响应头就行了
作用4:控制浏览器是否缓存(浏览器是默认设置缓存的)
setHeader("Expires",-1)--设置不缓存
setHeader("Cache-Control","no-cache")
setHeader("Pragma","no-cache");
作用5:请求重定向
意思是如果你向我借钱,我没钱,我让你去想我的同学借钱----两次请求,两次响应
setStatus(302)+setHeader("Location",路径)=sendRedirect("路径")
作用6:输出验证码(防止恶意注册,需要大量用到GUI知识)
Request对象---其实就是一个接口
ServletRequest---Request对象的接口,提供了一些响应的基本方法
HttpRequest---用的最多的类,在ServletRequest的基础上增加了一些http的方法,做了强化
他也是服务器创建的对象,是四大作用域之一,所以
生命周期:当服务器接受到请求的时候,request被创建,当请求结束的时候,request对象被服务器所销毁
作用范围:在整个请求链上面
作用看下面
作用1读取请求行中的信息
request.getRequestURL()--获得客户机完整的URL请求路径
request.getRequestURI()---获得客户机web应用的完整请求路径
request.getRemoteAddr()---获得客户机请求的IP地址(很邪恶的方法哦)
request.getQueryString()--获得客户机请求的参数部分
request.getRequestContext()---获得请求的web应用名称(比较重要,重定向中用的多)
request.getRequestMethod()---获得客户机请求的方式
作用2:读取请求头中的信息
request.getHeader(String name)--获得对应的请求头
request.getHeaderValues()
request.getIntHeader()
request.getDateHeader()---没标注的方法自己查API
作用3:数据共享
作为传递对象可以实现域的数据共享
作用4:获得请求中的具体对象信息
request.getParameter(String name)
作用5:请求转发(ServletContext也可以)和请求包含
和this.getServletContext().getRequestDispatcher(路径).forward(request,response);
request.getRequestDispatcher(路径).forward(request,response); 也可以实现请求转发
在请求转发中,所有之前写到response缓冲区里面的内容都会被清空,除了你写到响应头除外。如果你强制刷新到浏览器上面,服务器就会报错,所以这点要注意。
请求包含:在原有的基础上包含一些数据内容,把forward改为include即可。
到这里,关于Servlet的内容基本就写的7788差不多啦。
累死我了,越写到后面就越不想写了,很多内容被我偷懒了 不够详细,见谅。