java的Servlet
Http是协议
- 什么是协议
双方在交互、通讯的时候,遵守一种规范、规则。 - http协议
针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范。其实就是规定了客户端在访问服务器端的时候,要带上那些东西,服务器端返回数据的时候,也要带上什么东西。 - 版本
1.0
请求数据,服务器返回后,将会断开连接
1.1请求数据,返回服务器后,连接还会保持着。除非服务器 | 客户端 关掉。有一定的时间限制,如果都空着这个连接,那么后面会自己断掉。
Get和Post请求的区别
- post
- 数据以流的方式写过去,不会在地址上面显示。 现在一般提交数据到服务器使用的都是POST
- 以流的方式写数据,所以数据没有大小限制
- get
- 会在地址栏后面拼接数据,所以有安全隐患。一般从服务器获取数据,并且客户端也不用提交上面数据的时候,可以使用GET
- 能够带的数据有限,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
- 会使用简单的servlet
1.写一个类,实现接口Servlet
2.配置Servlet
3.会访问Servlet
- 会使用简单的servlet
- Servlet的生命周期
init 一次 创建对象 默认初次访问就会调用或者可以通过配置,让它提前load-on-startup
service 多次,一次请求对应一次service
destroy 一次, 一次销毁的时候 从服务器移除 或者 正常关闭服务器- 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
这个对象封装了客户端提交过来的而一切数据。
- 可以获取客户端请求头信息
//得到一个枚举集合
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);
}
}