servlet基础总结

什么是servlet

ServletServer Applet)是Java Servlet的简称,是小服务程序或服务连接器,是用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容.

狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的,一般情况下,人们将Servlet理解为后者。

第一个servlet

Sun公司在其API中提供了一个servlet接口,用户若想开发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:

编写一个Java类,实现servlet接口。

把开发好的Java类部署到web服务器中。

 

首先,我们要编写一个类,实现Servlet接口:

方法介绍

init( )

Servlet第一次被请求,Servlet容器就会开始调用这个方法初始化一个Servlet对象,但是这个方法在后续请求中不会在被Servlet容器调用。我们可以利用init( )方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。


service( )

每当请求Servlet时,Servlet容器就会调用这个方法。

第一次请求时,Servlet容器会先调用init(),然后调用service( ),在后续的请求中,Servlet容器只调用service方法。


destory

当要销毁Servlet时,Servlet容器就会调用这个方法,在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。


另外两个:

    getServletInfo( ),这个方法会返回Servlet的一段描述,可以返回一段字符串。

    getServletConfig( ),这个方法会返回由Servlet容器传给init()方法的ServletConfig对象。

生命周期

Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。

针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。

Servlet的整个生命周期内,Servletinit方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servletservice方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servletservice()方法,service方法再根据请求方式分别调用doXXX方法。

  实例化-->初始化-->服务->销毁

出生:(实例化-->初始化)第一次访问Servlet就出生(默认情况下)

活着:(服务)应用活着,servlet就活着

死亡:(销毁)应用卸载了servlet就销毁。

如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。

  举例:

  <servlet>

  <servlet-name>invoker</servlet-name>

  <servlet-class>org.apache.catalina.servlets.InvokerServlet</servlet-class>

  <load-on-startup>2</load-on-startup>

  </servlet>

l用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。

xml

由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

<servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name><servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name><url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。例如:

编写文件中的<servlet>\<servlet-mapping>节点。

<web-app>
	<servlet>
		<servlet-name>AnyName</servlet-name>
		<servlet-class>HelloServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>AnyName</servlet-name>
		<url-pattern>/demo/hello.html</url-pattern>
	</servlet-mapping>
</web-app>

 网址找到文件的过程就是这样的啦

至此,servelet访问过程大体完成:

Servlet 接口实现类

Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServletHttpServlet

Servlet --> GenericServlet --> HttpServlet  (继承HttpServlet)

HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。

HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServletdoGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGetdoPost方法,而不要去覆写service方法。

ServletRequset接口


    Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。

让我们来看一看ServletRequest接口的部分内容:

public interface ServletRequest {
  
 
    int getContentLength();//返回请求主体的字节数
 
    String getContentType();//返回主体的MIME类型
 
    String getParameter(String var1);//返回请求参数的值
 
}


其中,getParameter是在ServletRequest中最常用的方法,可用于获取查询字符串的值。

ServletResponse接口


    javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service()方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service()方法。ServletResponse隐藏了向浏览器发送响应的复杂过程。

    让我们也来看看ServletResponse内部定义了哪些方法:

public interface ServletResponse {
    String getCharacterEncoding();
 
    String getContentType();
 
    ServletOutputStream getOutputStream() throws IOException;
 
    PrintWriter getWriter() throws IOException;
 
    void setCharacterEncoding(String var1);
 
    void setContentLength(int var1);
 
    void setContentType(String var1);
 
    void setBufferSize(int var1);
 
    int getBufferSize();
 
    void flushBuffer() throws IOException;
 
    void resetBuffer();
 
    boolean isCommitted();
 
    void reset();
 
    void setLocale(Locale var1);
 
    Locale getLocale();
}


 

   其中的getWriter方法,它返回了一个可以向客户端发送文本的的Java.io.PrintWriter对象。默认情况下,PrintWriter对象使用ISO-8859-1编码(该编码在输入中文时会发生乱码)。

  在向客户端发送响应时,大多数都是使用该对象向客户端发送HTML。

还有一个方法也可以用来向浏览器发送数据,它就是getOutputStream,从名字就可以看出这是一个二进制流对象,因此这个方法是用来发送二进制数据的。

在发送任何HTML之前,应该先调用setContentType()方法,设置响应的内容类型,并将“text/html”作为一个参数传入,这是在告诉浏览器响应的内容类型为HTML,需要以HTML的方法解释响应内容而不是普通的文本,或者也可以加上“charset=UTF-8”改变响应的编码方式以防止发生中文乱码现象。

跳转

我们的网页可能会跳转到其他页面,怎么实现这个功能呢?有两种方法:

转发

重定向

他俩是什么意思呢。

举个例子:a给b打电话,聊了一会说,我找c。

这时候,b说,行,我给你转接到c手里,这就是转发。

这时候,b说,行,我给你c的电话号码,你自己打过去吧,然后a挂了电话给c打,这叫重定向。

请求转发

request.getRequestDispatcher(" targetURL").forward(request, response);

请求重定向

response.sendRedirect("targetURL")

转发是把请求转发给别人,重定向是发回给用户,用户发一个新的请求给新的servlet。

转发:

 

是服务器跳转,是同一个请求在服务器端传递,浏览器根本不知道发生了转发操作。

重定向:

是给用户一个新的地址,用户根据新的地址发送新的请求。

 

总结异同点:

相同点:都实现了跳转

不同点:

1、语法不同(废话)

2、跳转后,转发可以得到request里的内容,重定向得不到

3、地址栏路径不同,转发地址不变,重定向就是新的地址了。

4、原理不同,转发:就一个请求,重定向:两个

5、效率:转发>重定向(显而易见)

6、跳转范围不同:转发只能是当前项目,重定向随便

7、

写的路径不同:

转发不能写绝对路径,重定向可以;

转发写根路径不写上下文路径,代表当前项目根目录,重定向根路径需要写上下文路径,代表当前服务器;

建议都是用根路径。

8、转发会导致表单的重复提交,重定向不会。(刷新的话,转发是之前的地址,刷新就。。。)

9、转发不经过过滤器,重定向会经过(可以设置,让转发经过)

跳转方式的选择

必须的四种:

希望前后共享request,转发。

跳转到同一个WEB-INF目录下,只能转发。(因为不能直接访问里面,只能转发请求进去,重定向本质就是发了一个新请求,不可能)

跳到不同项目,只能重定向。。。(废话)

使用cookie存数据后要跳,只能重定向。转发后还没有呢。。(这个以后再说)

更优的四种:

转发效率高,尽量使用转发

但是使用转发需要解决重复提交表单问题。

注销之后一般用重定向

连续表单页面应使用重定向,尽量避免属性冲突

 

总体流程的例子

前三行为了解决中文乱码问题

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//设置请求编码格式
		req.setCharacterEncoding("utf-8");
		//设置相应编码格式
		resp.setCharacterEncoding("utf-8");
		resp.setContentType("text/html;charset=utf-8");
		//获取请求信息
		//处理请求信息
		FlowerService fs=new FlowerServiceImpl();
		List<Flower> lf=fs.getFlowerInfoService();
		//响应结果
		req.setAttribute("lf", lf);
		req.getRequestDispatcher("/show.jsp").forward(req, resp);	
	}
  • 203
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值