话说Servelt

    技术2026-05-22  8

    Servelt的生命周期

    Servelt的生命周期是由容器维护的,因此Servelt中必须包含无参构造器,以提供给容器创建Servelt对象。如果设置了load-on-startup,则当服务器启动时就会加载servelt,并且创建对象,进行初始化。如果没有设置则暂不加载。当用户访问Servelt时,容器会根据url中的信息加载对应的servelt,进行实例化和初始化,并且为这个请求创建一个独立的线程,创建request和response对象,并把servelt的实例交给这个线程。也就是说多个请求的线程拿到的是同一个servelt实例的引用。初始化完成后,进入执行阶段调用servelt的service()方法,在根据Method调用doGet或者是doPost方法。执行完成后,会终止给请求的线程,但是servlet对象并不会销往。一般情况下只有当服务器认为servlet不会被任何线程使用,或者是服务器中断等操作时servlet才会消亡,再这之前会执行destory方法。

    Servelt的初始化

    创建实例之后的第一件事情就是初始化。 初始化的目的有两个,一个是把容器中的配置信息ServletConfig和ServletContext传入servelt使其能够跟容器发生关系。 另外一个目的是利用Init只执行一次的特点,把一些大的对象,如数据库连接在init中进行初始化。能够节约资源。 servlet中有两个init方法,一个是有参的,一个是无参的,通常我们覆盖无参的,如果需要覆盖有参的则需要保留super.init()方法,否则在servelt中使用ServletConfig的时候会出现空指针错误。 初始化后servlet获得了两个对象ServletConfig和ServletContext。分别说明一下:

    ServletConfig

    一个Servelt一个。用于在DD中获取参数信息。DD中的内容为:<init-param><param-name>testParam</param-name><param-value>1</param-value></init-param>在servlet中通过getServletConfig().getInitParameter()方法,或者是直接用getInitParameter()获取配置信息

    ServletContext

    一个容器一个。包括了容器的信息,比如版本号等等。能够获取容器配置信息,在DD中的内容为:<context-param>可以通过getServletContext().getInitParameter("")获取配置的全局参数。

    servelt在初始化后就进入到了可以提供服务的状态,当需要的时候会调用service()方法,并且传入request和response两个参数。 这两个参数是容器把HTTP中的request和response封装成的对象。 request 已经知道了HTTP中的request主要包括了Method,url,头,如果是POST方法还会有包含了form表单信息的体部分。 request包括了很多的方法,以操作真正的HTTP request。主要有:

    getParameter()得到form中或者是url中的一个参数。request.getHeader("")。根据名称得到属性的值。Cookie[] cookies = request.getCookies()得到Cookies。getMethod()得到方法名称。getSession()得到session。getInputStream()得到输入流。当特殊情况下,比如需要传文件的时候可以使用流,流的内容只包含体,不包含头。

    从request中获取数据 表单元素有填充域,单选,多选等几种,我们都能够在request中进行获取。 比如页面元素如下:

    <form action=""> <table> <tr> <td>名称</td> <td><input name="username" type="text"/><input name="username" type="text"/></td> </tr> <tr> <td>性别</td> <td><input name="sex" type="radio" value="1"/>男<input name="sex" type="radio" value="0"/>女</td> </tr> <tr> <td>爱好</td> <td><input name="taste" type="checkbox" value="0"/>篮球<input name="taste" type="checkbox" value="1"/>足球</td> </tr> <tr> <td>班级</td> <td> <select name="grade"> <option value="1">一班</option> <option value="2">二班</option> </select> </td> </tr> <tr> <td>科目</td> <td> <select name="subject" multiple="multiple" > <option value="1">数学</option> <option value="2">语文</option> <option value="3">英语</option> </select> </td> </tr> <tr> <td>备注</td> <td> <textarea rows="2" cols="30"></textarea> </td> </tr> <tr> <td colspan="2"><button type="submit">提交</button></td> </tr> </table> </form>

     

    不指定method的情况下默认为:GET。以GET方式提交数据时,所有的数据都将显示在URL中,多选的数据比如爱好,将会显示为taste=0&taste=1的形式。当text不填写时获取的值为""。当其他不填写是为null在servelt中进行获取的时候,使用request.getParameterValues("taste");方法得到值的数组。使用request.getParameter("username")能够换取单项数据或者是多项数据的第一个。

    response

    一般情况下只是用来发送数据给客户端。使用setContentType()设置MIME,浏览器能够根据这个值来判断怎样处理传过来的数据时,播放音乐,还是展示文件等等。使用getWtiter()得到Writer,把HTML写回到浏览器还有一些其他的方法能够设置Cookie等等。当然通常情况下我们不会直接使用把HTML写回浏览器的方式,而是需要转到JSP中来代替这一过程的。

    除了发送HTML到客户端外,还能够通过设置ContentType来写入文件到客户端实现下载功能:

    response.setContentType("text/txt"); // response.setHeader("Content-Disposition", "filename=index.jsp"); // response.setHeader("Content-Disposition", "attachment;filename=index.jsp"); // response.setHeader("Content-Disposition", "inline;filename=index.txt"); response.setHeader("Content-Disposition", "attachment;filename=" + new String("你好.jsp".getBytes(),"ISO8859-1")); InputStream is = getServletContext().getResourceAsStream("/index.jsp"); // 以/开始,位置是相对于功能根目录的。 OutputStream os = response.getOutputStream(); int read = 0; byte[] bytes = new byte[1024]; while((read = is.read(bytes)) != -1){ os.write(bytes, 0, read); } os.flush(); os.close();

    代码比较简单,主要是分为两部分,一是设置头信息。Disposition-Disposition是MIME的描述信息,帮助浏览器判断如何处理文件,attachment是作为附件下载,inline是在浏览器中打开,filename是文件的名称。如果有中文名的时候需要转码。第二部分是把要传到浏览器的文件写入到response中获取到的输出流中。如果只是下载静态文件,也不需要这么麻烦,只需要使用a标签指向到一个可下载的路径就可以了。

    response除了把信息返回给客户端外,还能够对请求进行转发dispatch或者是重定向redirect,他们的区别在于:

    redirect是在客户端进行的。服务器把状态码301发送给客户端,客户端会重新发送那个请求给服务器。使用response.sendRedirect("")进行重定向。参数以/开头的是相对于服务器跟目录的,没有/是相对路径。重定向之后浏览器地址栏显示新的地址,并且不能够共享request.response是服务器端进行的,服务器访问一个地址,然后把结果传回浏览器。使用request.getRequestDispatcher("").forword()加上相对路径。能够共享request,并且浏览器的地址是没有变化的。转发的操作是不能够在out.write执行完之后进行的。

    到此servlet的相关功能介绍完毕。

    最新回复(0)