Servlet——其实就是一个java程序,运行在web服务器上,用于接收和响应客户端的http请求,更多的是配合动态资源的使用,无论访问静态资源还是动态资源,都会用到Servlet,Tomcat是servlet的容器,不过Tomcat里面已经定义好了一个DefalutServlet

 

 1、新建一个类,实现Servlet接口,不过要重写5个方法,可以继承HttpServlet,重写service方法

2、配置Servlet,告诉服务器,我们的应用有这么些个servlet

  2.1在web.xml配置以下信息:

    向Tomcat报告,我这里有个servlet,名字叫HelloServlet,具体路径就是包名+类名

    <servlet>
      <servlet-name>HelloServlet</servlet-name>
      <servlet-class>包名+类名</servlet-class>
    </servlet>

    注册servlet的映射,servlet-name:找到上面注册的具体servlet;

             url-pattern:在地址栏上的path,要以/开头
    <servlet-mapping>
      <servlet-name>HelloServlet</servlet-name>
      <url-pattern>/index</url-pattern>
    </servlet-mapping>

 

get请求会进入doGet,post请求会进入doPost,还有doPut,doDelete,这个涉及一种叫Rest开发风格,有时间可以深度学习,这里暂时知道

 

servlet的生命周期:

  实例化:当有第一次对应的servlet请求到达时就会实例化,只会创建一次,就是该类的构造函数随着容器启动就创建该servlet对象,可以在Web.xml中配置<load-on-startup>0</load-on-startup> 大于等于0,值越小优先级越高,在对应的servlet-class下面放置即可,一开服务器就会初始化,通常从2开始

  初始化:实例化后马上初始化,自动调用init的方法,也是只是运行一次,可以将只加载一次的工作放在init方法里面,例如是配置连接池,init有一个带参数的重载方法,如果调用了带参的方法,系统会默认调用带参的方法,不会调用无参的方法,如果带参函数里面有调用super,则会先调用无参的init的方法

  就绪:就绪状态,能够接受请求,准备运行service

    1.Servlet被初始化以后就处于能够响应请求的就绪状态。
    2.每个对Servlet的请求由一HttpServletRequest对象代表。
    3.Servlet给客户端的响应由一个HttpServletResponse对象代表。
    4.当客户端有一个请求时,容器就会将请求与响应对象转给Servlet,以参数的形式传给service方法。

  销毁:当服务器停止或重新启动时,自动销毁servlet对象,调用destroy方法

    1. Servlet容器在销毁Servlet对象时会调用destroy方法来释放资源。
    2.通常情况下Servlet容器停止或者重新启动都会引起销毁Servlet对象的动作:  

      2.1. 该项目从tomcat的里面移除。
      2.2. 正常关闭tomcat就会执行 shutdown.bat

 

ServletConfig——可以获取servlet在配置的一些信息,有以下的方法

getServletName()——获取到的是配置servlet里面servlet-name的文本<servlet-name>标签里面的内容

getInitParameter("address")——可以获取具体的初始化参数,入参为<param-name>,但是比较少用,配置如下,也是配置再servlet-class标签下,得到的是param-value值

<init-param>

  <param-name>address</param-name>

  <param-value>bejing</param-value>

</init-param>

getInitParameterNames()——获取所有的param-name,返回的是Enumeration<String>

getServletContext()——返回一个ServletContext对象,该对象包含关于servlet运行环境的信息

作用:

1. 未来我们自己开发的一些应用,使用到了一些技术,或者一些代码,我们不会。 但是有人写出来了。它的代码放置在了自己的servlet类里面。

2. 刚好这个servlet 里面需要一个数字或者叫做变量值。 但是这个值不能是固定了。 所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声明init-params

 

 

HttpServletRequest——请求对象,封装了客户端提交过来的一切数据

  getParameter("name")——获取请求体,简单来说可以获取form表单里面的input输入框对应name值的数据

  getHeaderNames()——获取一个枚举集合的请求Enumeration<String>

  getHeader(String name)——获取对应的请求头数据

  getHeader("User-Agent")——获取客户端类型:火狐:Firefox,

 

HttpServieResponse——响应对象

  setStatus()——设置状态码,302重新定位状态码

  setHeader(“Location”,"xxx.html")——设置响应头,Location定位跳转的位置

  以上两个方法相当于重定向,不过这种是早期的写法

  

字符串乱码问题:

接收数据:

  如果get请求:username = new String(username.getBytes("ISO-8859-1") , "UTF-8");也可在Tomcat里面设置以下内容:

  <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

  如果是post请求:request.setCharacterEncoding("UTF-8");不过要在获取数据前

发送数据:response.setCharacterEncoding("UTF-8");

     setHeader("Content-Type", "text/html;charset=UTF-8");——设置这份数据使用的码表

     getOutputStream().write("中文".getBytes("UTF-8"));——使用字节流的输出的时候设置格式

     setContentType("text/html;charset=UTF-8");——不管是字节流还是字符流,直接使用一行代码就可以了。

 

路径匹配:以 / 开始,如果以 * 开头代表任何请求都进入该方法

 

转发与重定向:

请求次数、地址栏是否改变、跨域、生成资源问题(是否可以访问WEB-INF下的内容)
转发的方法:
  request.getRequestDispatcher("/这里写网页的路径,如:/WEB-INF/mypage/loginsuccess.jsp").forward(request,response);

重定向的方法:
  response.sendRedirect("跳转的位置");如果需要跳转到WEB-INF文件外面的网页,直接写网页名即可,如果带了斜杠,则需要加上项目名才可以
转发和重定向不会结束方法,如果想调用了转发和重定向后结束方法,可以补一个return

 

转发:

  1.地址栏不会改变
  2.可以直接访问WEB-INF里面的资源
  3.转发中的路径项目根目录:http://localhost:8080/webTest2/
  4.只发一次请求
  5.因为是在项目根目录,所以不能跨域
  6.因为只发一次请求,所以速度回比较快
  7.共享域 请求对象都是同一个request,所以共用同一个request的作用域
  8.行为者 行为者是请求对象requset

重定向:

  1.地址栏会改变
  2.不可以直接访问WEB-INF里面的资源
  3.重定向中的斜杠代表服务器根目录:http://localhost:8080/
  4.会发两次请求
  5.因为是在项目根目录,所以能跨域,直接访问其他页面
  6.因为会发两次请求,所以速度回比较慢,客户端发送了第一次请求,服务器会返回具体的路径给客户端,然后客户端再重新发送一次请求访问具体的路径
  7.共享域 请求对象是不同的request,所以不能共用同一个request的作用域
  8.行为者,行为者是响应response,所以会丢失之前的请求数据和对象

重定向到转发:

先重定向发送一个请求,匹配到web.xml,web.xml再匹配到一个java类,java里面有转发的方法,转发到WEB-INF里面的资源,实现将所有的页面放到WEB-INF里面受到保护

页面请求的资源:

请求的资源包括图片,jq包等,因为页面请求的资源也相当于是一次重定向,而重定向是以服务器的根目录,相当于是WebContent开始,所以不需要加斜杠,直接写资源所在的位置,例如:jq放在WebContent里面的一个js文件夹里面,直接写js/jquery-1.11.3.js既可以

 

ServletContext——上下文,每个web工程都只有一个ServletContext对象,在哪里获取到的ServletContext对象都是同一个

全局参数

<context-param>

  <param-name>address</param-name>

  <param-value>深圳宝安</param-value>

</context-param>

ServletContext的获取:
  1.GenericeServlet(HttpServlet)提供的 getServletContext()
  2.ServletConfig提供的 getServletContext()
  3.HttpSession提供的 getServletContext()
  4.FilterConfig提供的 getServletContext()
  5.HttpServletRequest
以上的方法都能获取到上下文的对象、
作用:
  1.在Web范围内获取共享的资源:
    setAttribute("名字",对象),设置数据在上下文
    getAttribute("名字")获取对应的数据

    getInitParamater("全局参数的名字");获取web.xml全局参数<context-param>

  2.访问Web应用的静态资源:
    getRealPath(String path);
就是访问该项目WebContent里面的资源,path就是路径,如果写空字符,会得到项目在tomcat里面的根目录

    getResourceAsStram(String path);直接根据给定的文件的相对路径获取一个流

    这里的相对路径:工程在tomcat里面的根目录

    

ServletContext生命周期:

  服务器启动的时候创建,会位托管的每一个web应用程序,创建一个ServletContext对象

  从服务器移除托管,或者关闭服务器的时候销毁

ServletContext作用范围:只要在该项目里面,都可以取,

 

下载:

1、直接以超链接的方式下载,不写任何代码,也能够下载东西下来

让tomcat的默认servlet去提供下载:<br>
<a href="download/aa.jpg">aa.jpg</a><br>
<a href="download/bb.txt">bb.txt</a><br>
<a href="download/cc.rar">cc.rar</a><br>

原因是tomcat里面有一个默认的Servlet -- DefaultServlet 。这个DefaultServlet 专门用于处理放在tomcat服务器上的静态资源。

2、手动下载:

//前端:

<br>手动编码提供下载。:<br>
<a href="Demo01?filename=aa.jpg">aa.jpg</a><br>
<a href="Demo01?filename=bb.txt">bb.txt</a><br>
<a href="Demo01?filename=cc.rar">cc.rar</a><br>

<a href="Demo01?filename=中文.rar">cc.rar</a><br>



后端Servlet对应的代码:
     //
1. 获取要下载的文件名字 aa.jpg --- inputStream String fileName = request.getParameter("filename"); //如果前端的编码格式与后端的编码格式不一致,可以使用下面的代码解决乱码问题
     filename = new String(fileName.getBytes("前端编码格式"),"后端编码格式")
//2. 获取这个文件在tomcat里面的绝对路径地址 String path = getServletContext().getRealPath("download/"+fileName);
     
//让浏览器收到这份资源的时候, 以下载的方式提醒用户,而不是直接展示。 response.setHeader("Content-Disposition", "attachment; filename="+fileName); //3. 转化成输入流 InputStream is = new FileInputStream(path); OutputStream os = response.getOutputStream(); int len = 0 ; byte[]buffer = new byte[1024]; while( (len = is.read(buffer)) != -1){ os.write(buffer, 0, len); } os.close(); is.close();
posted on 2019-12-12 11:29  大景少  阅读(126)  评论(0编辑  收藏  举报