java的Servlet

java的Servlet

Http是协议

  • 什么是协议
    双方在交互、通讯的时候,遵守一种规范、规则。
  • http协议
    针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范。其实就是规定了客户端在访问服务器端的时候,要带上那些东西,服务器端返回数据的时候,也要带上什么东西。
  • 版本
    1.0
    请求数据,服务器返回后,将会断开连接
    1.1请求数据,返回服务器后,连接还会保持着。除非服务器 | 客户端 关掉。有一定的时间限制,如果都空着这个连接,那么后面会自己断掉。

Get和Post请求的区别

  • post
    1. 数据以流的方式写过去,不会在地址上面显示。 现在一般提交数据到服务器使用的都是POST
    2. 以流的方式写数据,所以数据没有大小限制
  • get
    1. 会在地址栏后面拼接数据,所以有安全隐患。一般从服务器获取数据,并且客户端也不用提交上面数据的时候,可以使用GET
    2. 能够带的数据有限,1kb大小

Web资源

在http协议中,规定了请求和响应双方,客户端和服务器端。与web相关的资源

有两种分类

  • 静态资源
    html、js、css
  • 动态资源
    servlet、jsp

Servlet

  • servlet:
    其实就是一个java程序,运行在我们的web服务器上,用于接收和响应 客户端 的http请求。
    更多的是配合动态资源来做。当作静态资源也需要使用到servlet,只不过是Tomcat里面已经定义好了一个DefaultServlet

Servlet的生命周期

  • 生命周期
    从创建到销毁的一段时间
  • 生命周期方法
    从创建到销毁,所调用的那些方法
  • init方法
    在创建该servlet的实例时,就执行该方法。
    一个servlet只会初始化一次,init方法只会执行一次
    默认情况下是:初次访问该servlet,才会创建实例。
  • service方法
    只要客户端来了一个请求,那么就执行这个方法了。
    该方法可以被执行很多次。一次请求,对应一次service方法的调用
  • destroy方法
    servlet销毁的时候,就会执行该方法
    1.该项目从tomcat的里面移除
    2.正常关闭tomcat就会执行shutdown.bat

doGet和doPost不算生命周期方法,所谓生命周期方法是指,从对象的创建到销毁一定会执行的方法,但是这两个方法,不一定会执行。

Servlet创建实例的时机 提前

1.默认情况下,只有在初次访问servlet的时候,才会执行init方法。有的时候,我们可能需要在这个方法里面执行一些初始化工作,甚至是做一些比较耗时的逻辑。
2.那么这个时候,初次访问,可能会在init方法中逗留太久的时间。那么有没有方法可以让这个初始化的时机提前一点。
3.在配置的时候,使用load-on-startup元素来指定,给定的数字越小,启动的时机就越早。一般不写负数,从2开始。
 <servlet>
 <servlet-name>MyServlet</servlet-name>
 <servlet-class>servlet.MyServlet</servlet-class>
<load-on-up>2</load-up-startup>
</servlet>

ServletConfig

Servlet的配置,通过这个对象,可以获取servlet在配置的时候的一些信息

//1.得到servlet配置对象 专门用在配置servlet的信息
	ServletConfig config = getServletConfig();
// 获取到的是配置servlet里面servlet-name 的文本内容
	String servletName  = config.getServletName();
	System.out.println("servletName="+servletName);

//2. 可以获取具体的某一个参数
	String address = Config.getInitParameter("address");
	System.out.println("address="+address);

//3. 获取所有的参数名称
	Enumeration<String> names = config.getInitParameterNames();
//遍历取出所有的参数名称
	while(names.hasMoreElements()) {
		String key  = (String) names.nextElement();
		String value = config.getInitParameter(key);
		System.out.println("key="+key + "value="+value);
	}

为什么需要有这个ServletConfig

1.未来我们自己开发的一些应用,使用到了一些技术,或者一些代码,我们不会。但是有人写出来了。它的代码放置在了自己的servlet类里面.
2.刚好这个servlet里面需要一个数字或这叫做变量值。但是这个值不能是固定了。所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声名init-params

重点:

  • http协议

    1.使用HttpWacht 抓包看一看http请求背后的细节
    2.基本了解 请求和响应的数据内容
    请求行、请求头、请求体
    响应行、响应头、响应体
    3.Get和Post的区别

  • Servlet

    1. 会使用简单的servlet
      1.写一个类,实现接口Servlet
      2.配置Servlet
      3.会访问Servlet
  1. Servlet的生命周期
    init 一次 创建对象 默认初次访问就会调用或者可以通过配置,让它提前load-on-startup
    service 多次,一次请求对应一次service
    destroy 一次, 一次销毁的时候 从服务器移除 或者 正常关闭服务器
  2. ServletConfig
    获取配置的信息,params

Servlet的配置方式:

1.全路径匹配
> 以/开始		/a/aa
> localhost:8080/项目名称/aa/bb
2.半路径匹配
> 以/开始,但是以*结束 /a/*
3.以扩展名匹配
> 写法:没有/以*开始.*扩展名*.aa*.bb

Configure:

 <init-param>
        <param-name>password</param-name>
        <param-value>123456</param-value>
    </init-param>
ServletConfig config = getServletConfig();
String user=config.getInitParameter("user");
String pwd=config.getInitParameter("pwd");
System.out.println(user + "  " + pwd);
String servletName  = config.getServletName();
System.out.println("servletName="+servletName);
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>com.cn.zhu.servlet.AdminServlet</servlet-class>
<init-param>
	<param-name>name</param-name>
	<param-value>/WEB-INF/config.properties</param-value>
</init-param>
</servlet>

在这里插入图片描述

 ServletConfig config=getServletConfig();
 //创建ServletConfig对象
  String value=config.getInitParameter("name");
  System.out.println("value的值"+value);
  //获得路径
  Properties properties=new Properties();
  //加载文本 获得流资源
  properties.load(config.getServletContext().getResourceAsStream(value));
  // 获得属性文件中的name和pass的值

 
  String name=properties.getProperty("name");
  String pass=properties.getProperty("pass");
  // 从界面中获取用户输入的值
  String username=request.getParameter("Username");
  String password= request.getParameter("password");
<servlet>
<servlet-name>11</servlet-name>
<init-param>
	<param-name>data</param-name>
	<param-value>123</param-value>
</init-param>	
  </servlet>
ServletConfig config=getServletConfig();
//得到指定值
String value =config.getInitParameter("data");
System.out.println("data"+"   "+value);

//得到所有值
Enumeration e=config.getInitParameterNames();
while(e.hasMoreElements()) {
	String name=(String)e.nextElement();
	String value2=config.getInitParameter(name);
	System.out.println(name+"   "+value2);
	}

使用提供的参数因为实在servlet里面的,所以只能够被一个servlet使用,所以,当多个servlet需要使用同一个参数时,可以将这个参数放在servlet外面,使用来进行设置。

使用资源注射的方式的时候,要使用标签来配置数据信息

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>getParam</servlet-name>
    <servlet-class>getParam</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>getParam</servlet-name>
    <url-pattern>/getParam</url-pattern>
  </servlet-mapping>

  <env-entry>
    <env-entry-name>name</env-entry-name>
    <env-entry-value>xm99</env-entry-value>
    <env-entry-type>java.lang.String</env-entry-type>
  </env-entry>

  <env-entry>
    <env-entry-name>password</env-entry-name>
    <env-entry-value>123456</env-entry-value>
    <env-entry-type>java.lang.String</env-entry-type>
  </env-entry>
</web-app>

而在标签中,,,三个标签的顺序不能发生改变,如果顺序不对的话,会报错。

在方法中进行数据注入:

public class getParam extends HttpServlet {

    private @Resource(name = "name") String name;

    private @Resource(name = "password") String password;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        System.out.println(name);
        System.out.println(password);

    }
}
  • String getServletName() – 获取当前Servlet在web.xml中配置的名字
  • String getInitParameter(String name) – 获取当前Servlet指定名称的初始化参数的值
  • Enumeration getInitParameterNames() – 获取当前Servlet所有初始化参数的名字组成的枚举
  • ServletContext getServletContext() – 获取代表当前web应用的ServletContext对象

ServletContext

Servlet上下文

每个web工程都只有一个ServletContext对象,说白了也就是不管在哪个servlet里面,获取到的这个类的对象都是同一个

如何得到对象

//1.获取对象
		ServletContext context = getServletContext();

作用:

.1.获取全局配置参数
 2.获取web工程中的资源
 3.存取数据,servlet间共享数据,域对象

可以获取web应用中的资源

1.获取资源在tomcat的中的绝对路劲
	先得到路径,然后自己new InputStream
	context.getRealPath("")			//这里得到的是项目在tomcat中的根目录
	String path = conext.getRealPath("myfirsrjavaweb/myfirstjavaweb/config.properties");		//根路径加上相对路径
2.getResourceAsStream 获取资源流对象
	直接个相对的路径,然后获取流对象。

通过classloader去获取web工程下的资源

在这里插入图片描述

使用ServletContext存取数据:

  <context-param>
    	<param-name>contextparam</param-name>
    	<param-value>我是context-param</param-value>
   </context-param>
ServletContext ServletContext = getServletContext();
String context = ServletContext.getInitParameter("contextparam");
System.out.println(context);

ServletContext何时创建,何时销毁?作用域

服务器启动的时候,会为托管的每一个web应用程序,创建一个ServletContext对象
从服务器移除托管,或者是关闭服务器
只有在这个项目里面,都可以取。只要是同一个项目。A项目存,在B项目取,是取不到的?ServletContext对象不同.

HttpServletRequest

这个对象封装了客户端提交过来的而一切数据。

  1. 可以获取客户端请求头信息
    //得到一个枚举集合
    Eumeration headerNames = request.getHeaderNames();
    while(headerNames.hasMoreElements(){
    String name = (String)headerNames.nextElement();
    String value = (String)request.getHeader(name);
    System.out.println(name+"="+value);
    }

2.获取中文数据

客户端提交数据给服务器端,如果数据中带有中文的话,有可能会出现乱码情况,那么可以从参照以下方法解决。

get请求

get请求过来的数据,在url地址栏上就已经经过编码了,所以我们取到的就是乱码

tomcat收到了这批数据,getParameter默认使用iso-8859-1去解码

先让文字回到iso-8859-1对应的字节数组,然后在按utf-8组拼接字符串
username = new String(username.getBytes(“ISO-8859-1”,“utf-8”)

也可以在tomcat里面做设置处理conf/server.xml加上URIEncoding=“utf-8”
修改 Connector 标签里面的参数

psot请求

request.setCharacterEncoding(“utf-8”); //这个设置一定要在getParameter之前

指定浏览器栏这份数据使用的码表
response.setCharacterEnding(“utf-8”);
response.setHeader(“Content-Type”,“text/html”,charset=utf-8")

下载小demo

在这里插入图片描述

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	让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>

	<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>
	

</body>
</html>
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Demo01
 */
public class Demo01 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//1. 获取要下载的文件名字 aa.jpg  --- inputStream
		String fileName = request.getParameter("filename");
		
		//2. 获取这个文件在tomcat里面的绝对路径地址
		String path = getServletContext().getRealPath("download/"+fileName);
		
		//让浏览器收到这份资源的时候, 以下载的方式提醒用户,而不是直接展示。 
		response.setHeader("Content-Disposition", "attachment; filename="+fileName);
		
//		response.setStatus(302);
//		response.setHeader(Location, "login_success.html");
		
		//
		//response.sendRedirect("login_success.html");
		
		//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();
	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
发布了54 篇原创文章 · 获赞 0 · 访问量 322

猜你喜欢

转载自blog.csdn.net/qq_42977003/article/details/103097001