servlet的概念
它是javaEE的一个接口,在使用时需要导入servlet-api的jar包
第一个程序
针对web.xml配置文件
针对注解做配置
注:不同的包相同的类名,name不能起一样的,value也不能起一样的,必须有区分。
需要注意的是:name属性并不影响Servlet的URL映射,它只是作用于应用程序中标识和引用Servlet,URL映射是通过value或者urlPatterns属性来指定。
如果两者都做了配置,则web.xml文件做的配置优先级大于注解
servlet生命周期
init方法和空参构造器在服务器启动时会调用一次,service方法是每一次访问都会被调用,destory方法在程序结束的时候才会调用,init方法可以用来初始化参数,destory方法可以用来释放资源或者是对程序做一些善后处理。
表单提交加不加/问题
由于我们的项目是有项目名的,所以当我们在表单提交的时候如果加上/,路径就是 http://localhost:8080==/,如果不加/, http://localhost:8080/项目路径名(但是这种情况下,当我们的form表单不在根目录下时,我们需要手动添加form表单所在的包名,但是在表单提交之后,他会在该路径下继续寻找提交的路径,会出现找不到的情况)因此针对上述两种方式,我们有两种解决方案
加上项目名
使用<base>
表单提交对应关系
每个servlet的访问路径可以设置多个,是数组,但是在写多个的时候要用{}包含,不能使用[]
value==urlPatterns
继承HttpServlet类
由于我们在进行业务逻辑处理的时候不需要实现这么多方法,因此我们选择使用类去继承HttpServlet这个抽象类,而不是去直接实现Servlet接口,如下关系图
请求提交方式
post
用于form表单提交,html网页中除了表单能进行post提交....其他的元素都是采用get提交方式。
get
所有提交都可以使用该方式
在doPost中写doGet方法,即使采用post方法也可以调用到get方法,这样核心业务逻辑只需要全部写在get方法里面就行了,代码不会冗余,反向操作也是合理的,如果直接通过地址输入Servlet,也是get提交。
service方法对请求方式进行分发
servlet是通过service方法进行请求分发,他会将我们的请求分给doGet方法,或者分给doPost方法,然后去这两个方法中进行逻辑处理太麻烦了,我们可以直接在service方法里面进行逻辑处理,不对请求进行分发。
分析service方法
我们每次重写都是重写父类自定义的service方法,因为这个方法里面的参数对象所拥有的方法是我们需要的,如果我们使用原生的对象需要进行强制类型转换。
上述两个参数的类型关系如下
init()方法与init(ServletConfig config)方法的区别
ServletConfig类
该类是每创建一个Servlet,就会有一个这样的配置对象,它的作用是
在init()方法里面初始化配置和资源,ServletConfig对象可以调用方法获取配置参数信息
配置文件设置初始化参数
注解设置初始化参数
ServletContext 类
1、ServletContext 是一个接口,它表示Servlet 上下文对象
2、一个web 工程,只有一个ServletContext 对象实例。
3、ServletContext 对象是一个域对象。
4、ServletContext 是在web 工程部署启动的时候创建。在web 工程停止的时候销毁。
一个工程启动,它的ServletContext 对象都是同一个,直至销毁后重新开启才改变
- 以下是在同一个工程启动中通过不同的servlet访问ServletContext 对象
- 以下是销毁后重新建立的ServletContext 对象
1、获取web.xml 中配置的上下文参数context-param
<context-param>
<param-name>username</param-name>
<param-value>yll</param-value>
</context-param>
<context-param>
<param-name>email</param-name>
<param-value>2421@qq.com</param-value>
</context-param>
通过ServletConfig 对象获取ServletContext 对象
package com.sun.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "HelloServlet6",value = "/HelloServlet6")
public class HelloServlet6 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp){
ServletConfig servletConfig = getServletConfig();
ServletContext servletContext = servletConfig.getServletContext();
System.out.println("servletContext = " + servletContext);
System.out.println(servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("email"));
}
}
直接调用getServletContext()方法获取ServletContext 对象
package com.sun.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "HelloServlet6",value = "/HelloServlet6")
public class HelloServlet6 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp){
ServletContext servletContext = getServletContext();
System.out.println("servletContext = " + servletContext);
System.out.println(servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("email"));
}
}
我们可以直接使用第二种方式进行创建,因为该方法在父类中基于第一种方式已经被封装好了
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
此地方有控制台乱码问题,可以在控制台解决
4、像Map 一样存取数据
通过键值对的方式,调用方法getAttribute和setAttribute进行赋值和取值,由于我们工程启动只存在一个servletContext对象(是一个全局作用域),所以通过这个对象建立的所有数据在一个工程里面所有的servlet都是可以共享的。只有当我们把数据删除或者关闭工程时,数据才会消失
HTTP协议
Get请求
Post请求
两者各自的使用场景
MIME类型(响应类型)
package com.sun.bean;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/ImageServlet1")
public class ImageServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 采用的是文件输入流和输出流的方法读取,1.先读取文件的绝对路径 2.把文件的大小赋值给byte数组
* 3.使用输入流读取文件的大小(也就是本张照片的大小) 4.设置响应类型 5.使用文件流写出,也是写文件的大小
* 6.刷新流,关闭流
*/
ServletContext servletContext =getServletContext();
String realPath = servletContext.getRealPath("imgs/2.webp");
System.out.println("realPath = " + realPath);
FileInputStream fileInputStream = new FileInputStream(realPath);
int size = fileInputStream.available();
byte[] bytes = new byte[size];
fileInputStream.read(bytes);
fileInputStream.close();
resp.setContentType("image/webp");
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
}
}
常见的请求和响应头的作用
当我们在做项目的时候,我们可以通过请求的状态和响应头的数据做相应的数据对照,以便于找出我们程序中是否存在BUG或者未知的问题。
servelt的注意事项
在不同的包中,也不能使用相同的value或者urlPattern值,否则会报出如下异常
servlet学习的用法和作用总结
比较ServletConfig和ServletContext两个对象的区别
在上述的笔记中,我们可以看到ServletConfig和ServletContext这两个对象都可以调用getInitParameter这个方法,并且获取到参数的值,在此再次总结一下,虽然都可以获取到参数值,但是两者有差别
首先ServletConfig对象是Servlet级别的,它只能获取到该Servlet的参数,但是ServletContext这个对象是全局域,一个Web项目会有多个Servlet,ServletContext这个对象可以获取到整个Web应用程序级别的初始化参数,并且这个参数在我们进行开发中可以用来共享<例如共享数据库连接池的最大连接数,缓存大小等>
获取初始化参数的目的:配置数据库连接参数,获取环境变量<开发环境和生产环境>
getInitParameter方法和getAttribute方法的区别的区别
getInitParameter()方法和getAttribute()方法是用于获取初始化参数和属性值的方法,但它们之间有一些区别:
1. 用途不同:getInitParameter()方法用于获取Servlet或ServletConfig中的初始化参数(可以在web.xml或者注解方式配置)的值,而getAttribute()方法用于获取Servlet或ServletContext中存储的属性的值。
2. 获取位置不同:getInitParameter()方法是在Servlet或ServletConfig对象中调用的,而getAttribute()方法是在Servlet或ServletContext对象中调用的。
3. 存储方式不同:初始化参数是在web.xml文件或注解中配置的,而属性是通过代码动态设置的,通过后续servlet讲解中的请求转发设置属性值可以更加理解。
4. 作用范围不同:初始化参数的作用范围是在Servlet或ServletConfig对象内部,而属性的作用范围是在整个Servlet或ServletContext中共享的。
5. 获取方式不同:getInitParameter()方法需要传入参数名称来获取对应的初始化参数的值,而getAttribute()方法需要传入属性名称来获取对应的属性值,通过后续servlet讲解中的请求转发设置属性值可以更加理解。
Servlet用在哪些地方
它是客户端和服务器端的中介,它可以把客户端的数据提交到服务器端进行处理,也可以把服务器端处理的结果回响给客户端,例如登录/注册功能,数据提交给服务器端,服务器端进行数据处理,然后回响一个登录/注册成功或者失败给客户端,它是构建动态,交互式和可扩展的Web应用程序的重要组件之一。
Servlet容易出错的地方
在访问时,有没有工程名容易出现404错误,或者错误使用/也容易出现404错误。一个Web项目里面,多个Servlet不能同名,url访问路径也不能同名,否则会报如下异常,可以没有Servlet名字,但是不能没有url映射路径。