浅析动态web编程语言--Servlet

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差不多啦。
累死我了,越写到后面就越不想写了,很多内容被我偷懒了  不够详细,见谅。

你可能感兴趣的:(java,servlet,编程语言,web)