草庐IT

Javaweb(三) - servlet&filter

xiaoqigui 2023-04-20 原文

1、什么是servlet

第一个servlet应用程序,实现servlet接口
定义:凡是实现了servlet api接口(或者继承servlet api接口的实现类)的类就是servlet应用程序;

命周期:

  1. 创建servlet应用程序的实例:只会执行一次,在首次通过url-pattern映射访问时,创建实例;
  2. 初始化init方法:只会执行一次,在创建完servlet应用程序的实例后,立刻调用,一般都是用户初始化servlet应用程序;
  3. 业务处理service方法:执行多次,每当访问请求映射到servlet应用程序时,都会调用service方法,进行请求处理;
  4. 销毁destroy方法:只会执行一次,在web应用程序卸载时,统一调用,多用户释放服务器资源;

2、创建Servlet的三种方式

2.1 实现 servlet接口

public class HelloServlet implements Servlet {
	// 空参构造
	public  HelloServlet() {
		System.out.println("---------HelloServlet 空参构造--------------");
	}
	
	@Override
	public void destroy() {
		System.out.println("---------HelloServlet destroy--------------");
	}

	@Override
	public ServletConfig getServletConfig() {
		System.out.println("---------HelloServlet getServletConfig--------------");
		return null;
	}

	@Override
	public String getServletInfo() {
		System.out.println("---------HelloServlet getServletInfo--------------");
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("---------HelloServlet init--------------");	
	}

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		System.out.println("---------HelloServlet service--------------");
	}

}

2.1.1 servlet的生命周期

//第一次访问映射路径:
---------HelloServlet 空参构造---------
---------HelloServlet init-----------(//如果配置了load-on-startup 项目启动前面两步就会立刻执行)
    
---------HelloServlet service--------(//每次访问映射路径都会调用此方法)

---------HelloServlet destroy--------(//关闭服务才会调用)

2.2 继承 GenericServlet

public class HelloServlet2 extends GenericServlet{
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    }
}

2.3 继承 HttpServlet

public class StudentInfoServlet extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        // 一般直接在get请求处理方法中,直接调用post方法,实现两种请求统一处理
        //doPost(request, response);
    }
}

3、Servlet 的注册配置

3.1 注册

  <!-- 注册第一个 servlet应用程序 -->
 <servlet>
 	<!-- servlet应用程序的别名 -->
    <servlet-name>helloServlet</servlet-name>
    <!-- servlet应用程序的全类名 -->
    <servlet-class>com.kgc.servlet.HelloServlet</servlet-class>
 </servlet>

 <!-- 映射第一个servlet应用程序 -->
 <servlet-mapping>
 	<servlet-name>helloServlet</servlet-name>
 	<url-pattern>/hello</url-pattern>
 </servlet-mapping>

3.2 模糊映射

 <servlet-mapping>
 	<servlet-name>helloServlet</servlet-name>
 	<!-- 匹配方法 前匹配 /user/* 等等 -->
 	<!-- <url-pattern>/*</url-pattern> -->
 	<!-- 匹配方法 后匹配 -->
 	<!--<url-pattern>*.do</url-pattern>-->
 	<!-- 不能 /*.xx  两种一起使用 -->
 </servlet-mapping>

3.3 初始化参数

3.3.1 单个servlet内部初始化参数

 <servlet>
    <servlet-name>helloServlet</servlet-name>
    <servlet-class>com.kgc.servlet.HelloServlet</servlet-class>
    <!--  指定servlet内部初始化参数,必须在load-on-startup之前 -->
    <init-param>
    	<param-name>key</param-name>
    	<param-value>value</param-value>
    </init-param>
 </servlet>

3.3.2 获取单个servlet内部初始化参数

@Override
public void init(ServletConfig config) throws ServletException {
    System.out.println("---------HelloServlet init--------------");

    //获取当前servelt初始化参数 
    //通过 config 对象获取
    String encoding = config.getInitParameter("encoding");
    System.out.println("******* servlet内部初始化参数 encoding = "+encoding+"******");
}

3.3.3 全局servlet初始化参数

<context-param>
    <param-name> key </param-name>
    <param-value> value </param-value>
</context-param>

3.3.4 获取全局servlet初始化参数

//获取全局servelt初始化参数
//通过ServletContext 对象获取
String encodingContext = config.getServletContext().getInitParameter("encoding");
System.out.println("**** servlet全局初始化参数 encodingContext = "+encodingContext+"*****");

3.3.5 servlet 的启动优先级

默认情况下,启动是不会创建实例和初始化

配置了load-on-startup,servlet应用程序就会在服务器启动时创建实例并初始化

允许值为正整数(可以为0)负数不可以,一般为1,值的作用是指定servlet应用程序的创建时机,值越小优先级,越高,越早创建实例并初始化

 <load-on-startup>1</load-on-startup>

3.3.6 欢迎页面

<!-- 欢迎页面可以设计多个,在web.xml中越靠上优先级越高 -->
<welcome-file-list>
	<welcome-file>login.html</welcome-file>
</welcome-file-list>

3.3.7错误页面

<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

4、相对路径和绝对路径

通过servlet的跳转使用相对路径,容易出错,会导致缺少部分路径,而找不到资源

一般使用绝对路径,进行跳转;

//获取项目跟路径
<%=request.getContextPath()%>  //获取跟路径后再根据实际情况进行路径拼接

5、filter

5.1 创建过滤器

实现Filter的应用就是过滤器;

public class MyFirstFilter implements Filter{
	public MyFirstFilter() {
		System.out.println("-----MyFirstFilter 空参构造 ------");
	}
	@Override
	public void destroy() {
		System.out.println("-----MyFirstFilter destroy ------");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----MyFirstFilter doFilter ------");
		//FilterChain 是决定请i去是否放行的操作对象,如果请求放行,必须要调用FilterChain的请求过滤方法doFilter
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("-----MyFirstFilter init ------");
	}
}

5.2 filter 注册与映射

<!-- 注册过滤器first:配置内容和servlet基本一样,就是标签不一样 -->
<filter>
    <filter-name>myFirstFilter</filter-name>
    <filter-class>com.kgc.filter.MyFirstFilter</filter-class>
</filter>
<!-- 过滤器first映射 -->
<filter-mapping>
    <filter-name>myFirstFilter</filter-name>
    <url-pattern>/filter01.jsp</url-pattern>
    <!-- filter的映射也可以模糊匹配 /* 等等 -->
</filter-mapping>

5.3 filter 的初始化参数

<init-param>
    <param-name>encoding</param-name>
    <param-value>utf-8</param-value>
</init-param>

获取参数:

//一些配置的初始化参数可以通过 filterConfig.getInitParameter(key) 获取
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    this.encoding = filterConfig.getInitParameter("encoding");
    System.out.println("获取字符集过滤器中的初始化编码:"+this.encoding);
}

5.4 filter 的执行顺序

web.xml中映射顺序,越上面的越先执行;

MySecondFilter

public class MySecondFilter implements Filter {
	@Override
	public void destroy() {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----1.MySecondFilter  doFilter before ------");
		chain.doFilter(request, response);
		System.out.println("-----2.MySecondFilter  doFilter after ------");
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}

MyThridFilter

public class MyThridFilter implements Filter {
	@Override
	public void destroy() {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("-----3.MyThridFilter doFilter before ------");
		chain.doFilter(request, response);
		System.out.println("-----4.MyThridFilter doFilter after ------");
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}

filterTarget.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		System.out.println("-----5.Filter Target Page-----");
	%>
 	<h2>Filter Target Page</h2>
</body>
</html>

web.xml

<!-- second -->
<filter>
    <filter-name>mySecondFilter</filter-name>
    <filter-class>com.kgc.filter.MySecondFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>mySecondFilter</filter-name>
    <url-pattern>/web3filter01/filterTarget.jsp</url-pattern>
</filter-mapping>

<!-- third -->
<filter>
    <filter-name>myThridFilter</filter-name>
    <filter-class>com.kgc.filter.MyThridFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>myThridFilter</filter-name>
    <url-pattern>/web3filter01/filterTarget.jsp</url-pattern>
</filter-mapping>

运行结果顺序:

//执行顺序
-----1.MySecondFilter  doFilter before ----
-----3.MyThridFilter doFilter before ------
-----5.Filter Target Page-----
-----4.MyThridFilter doFilter after -------
-----2.MySecondFilter  doFilter after ------

5.5 编码过滤器

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    //this.encoding 编码名可以存放在过滤器初始化参数中,通过filterConfig.getInitParameter("encoding");获取
    //poet请求乱码处理
    request.setCharacterEncoding(this.encoding);
    //响应编码
    response.setContentType("text/html; charset=UTF-8");
    response.setCharacterEncoding(this.encoding);

    //请求放行
    chain.doFilter(request, response);
}

有关Javaweb(三) - servlet&filter的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  8. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

随机推荐