目录
什么是Servlet?
- 是Servlet Applet的缩写,称为小服务程序或服务连接器
- 是Java编写的服务器端程序,具有独立于平台和协议的特性
- Servlet是接口,是一套Java Web开发的规范,是基于Java的动态网站开发技术
什么是JSP?
- Servlet 是第一代 Java Web 开发技术,它将 HTML 代码以字符串的形式向外输出,编写 HTML 文档就是在拼接字符串
- JSP是第二代 Web 开发技术,允许 HTML 代码和 JSP 代码分离,可以在 HTML 文档中直接嵌入 JSP 代码
Servlet的容器是什么?
用来管理程序员编写的 Servlet 类;
是 Servlet 代码的运行环境(运行时),除了实现 Servlet 规范定义的各种接口和类,为 Servlet 的运行提供底层支持,还需要管理由用户编写的 Servlet 类,比如实例化类(创建对象)、调用方法、销毁类等。
Servlet的容器有哪些?
实现Servlet规范的产品:
- Tomcat
- Weblogic
- Jetty
- Jboss
- WebSphere
- 运行 PHP 网站一般选择 Apache 或者 Nginx;
运行 ASP/ASP.NET 网站一般选择 IIS;
运行 Python 网站一般选择内置的 WSGI 服务器模块——wsgiref
Servlet的容器的作用?
是负责处理客户请求,Servlet容器获取请求,然后调用某个Servlet,并把Servlet的执行结果返回给客户
如何创建并部署web应用?
1、新建javaweb工程
- 先创建一个java空项目
- 在新建好的项目上点击右键,点Add Framework Support
- 点击导入Web Application,点击ok即可
2、配置TomCat启动项目
- 配置Tomcat,点击右上角的编辑配置,点击+号,找到Tomcat Server
- 选择一个本地下载好的Tomcat
- 在右边的部署栏Deployment中点击+号,添加构建
- 这里可以选择只保留“/”
- 选择热加载,点击ok完成运行环境部署
3、创建和访问Selevt
第一种:
- 先新建一个Servlet,打开servlet后会发现有报错,找不到servlet.http包,需要我们导入servlet-api包
- 在File菜单栏下找到项目组织–Project Structure
- 找到 Libraries,点击+号,选择java,找到你Tomcat的安装位置下的lib文件夹,下面有 servlet-api.jar,选择导入
- 然后在servlet上加上注解 @WebServlet(name = “Servlet”,urlPatterns = “/Servlet”)
- 添加一个映射路径,访问Servlet
- 打开浏览器,在路径后加上映射名,就可以访问到我们项目下刚刚新建的servlet了
第二种:
- 先在项目的web---WEB-INF的包下,创建一个lib包
- 将Tomcat的安装位置下的lib文件夹,下面有 servlet-api.jar,复制粘贴过来
- 鼠标右击,点击添加为库
- 之后再创建一个Servlet,上面会直接给出注解@WebServlet(name = “Servlet”,urlPatterns = “/Servlet”),名字需要唯一
- 打开浏览器,在路径后加上映射名,就可以访问了
Servlet的创建方式有哪几种?
Servlet的创建方式有3种:
- 实现 javax.servlet.Servlet 接口,重写其全部方法。
- 继承 javax.servlet.GenericServlet 抽象类,重写 service() 方法。
- 继承 javax.servlet.http.HttpServlet 抽象类,重写 doGet() 或 doPost() 方法。
实例:
package com.m0_54698212.servlet;
import javax.servlet.*;
import java.io.IOException;
public class MyServlet implements Servlet {
int count=0;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("servlet初始化");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("提供服务,处理请求");
System.out.println(count++);
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
package com.m0_54698212.servlet;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class MyServlet2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("处理请求");
}
}
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "TestServlet", value = "/api/test")
public class TestServlet extends HttpServlet {
public TestServlet(){
System.out.println("实例化:创建对象");
}
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("初始化");
}
@Override
public void destroy() {
System.out.println("销毁");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理get请求");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理post请求");
doGet(request,response);
}
}
顶级接口Servlet的方法:
返回值 | 方法 | 备注 |
---|---|---|
void | init(ServletConfig config) | Servlet 实例化之后,由 Servlet 容器调用,用来初始化 Servlet 对象。该方法只能被调用一次。 参数 config 用来向 Servlet 传递配置信息。 |
void | service(ServletRequest req,ServletResponse res) | Servlet 容器调用该方法处理客户端请求。 |
void | destroy() | 服务器关闭、重启或者 Servlet 对象被移除时,由 Servlet 容器调用,负责释放 Servlet 对象占用的资源。 |
ServletConfig | getServletConfig() | 该方法用来获取 ServletConfig 对象,该对象中包含了 Servlet 的初始化参数。 |
String | getServletInfo() | 该方法用于获取 Servlet 的信息,例如作者、版本、版权等。 |
GenericServlet 抽象类的方法:
返回值 | 方法 | 备注 |
---|---|---|
String | getInitParameter(String name) | 返回名字为 name 的初始化参数的值,初始化参数在 web.xml 中进行配置。如果参数不存在,则返回 null。 |
Enumeration<String> | getInitParameterNames() | 返回 Servlet 所有初始化参数的名字的枚举集合,若 Servlet 没有初始化参数,返回一个空的枚举集合。 |
ServletContext | getServletContext() | 返回 Servlet 上下文对象的引用。 |
String | getServletName() | 返回此 Servlet 实例的名称。 |
@WebServlet 注解的属性有哪些?
属性名 | 类型 | 标签 | 描述 | 是否必需 |
---|---|---|---|---|
name | String | <servlet-name> | 指定 Servlet 的 name 属性。 如果没有显式指定,则取值为该 Servlet 的完全限定名,即包名+类名。 | 否 |
value | String[ ] | <url-pattern> | 该属性等价于 urlPatterns 属性,两者不能同时指定。 如果同时指定,通常是忽略 value 的取值。 | 是 |
urlPatterns | String[ ] | <url-pattern> | 指定一组 Servlet 的 URL 匹配模式。 | 是 |
loadOnStartup | int | <load-on-startup> | 指定 Servlet 的加载顺序。 | 否 |
initParams | WebInitParam[ ] | <init-param> | 指定一组 Servlet 初始化参数。 | 否 |
servlet的生命周期?
- 实例化:通过构造方法实例化
实例化时间1、第一次请求时 2、设置load-on-startup属性后,随着tomcat启动实例化
- 初始化:init方法
- 服务:service方法
- 销毁:destroy方法,tomcat关闭时才销毁
servlet的工作原理?
客户端发起请求(某个servlet)-----> tomcat收到请求-----> 实例化Servlet(1次)----->处理请求(service)---> doGet|doPost-----> 当tomcat关闭时(销毁servlet实例)
HttpServletRequest 接口是什么?
HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象
常用方法:
获取请求行信息:
返回值类型 | 方法声明 | 描述 |
---|---|---|
String | getMethod() | 该方法用于获取 HTTP 请求方式(如 GET、POST 等)。 |
String | getRequestURI() | 该方法用于获取请求行中的资源名称部分,即位于 URL 的主机和端口之后,参数部分之前的部分。 |
String | getQueryString() | 该方法用于获取请求行中的参数部分,也就是 URL 中“?”以后的所有内容。 |
String | getContextPath() | 返回当前 Servlet 所在的应用的名字(上下文)。对于默认(ROOT)上下文中的 Servlet,此方法返回空字符串""。 |
String | getServletPath() | 该方法用于获取 Servlet 所映射的路径。 |
String | getRemoteAddr() | 该方法用于获取客户端的 IP 地址。 |
String | getRemoteHost() | 该方法用于获取客户端的完整主机名,如果无法解析出客户机的完整主机名,则该方法将会返回客户端的 IP 地址。 |
获取 form 表单的数据:
返回值类型 | 方法声明 | 功能描述 |
---|---|---|
String | getParameter(String name) | 返回指定参数名的参数值。 |
String [ ] | getParameterValues (String name) | 以字符串数组的形式返回指定参数名的所有参数值(HTTP 请求中可以有多个相同参数名的参数)。 |
Enumeration | getParameterNames() | 以枚举集合的形式返回请求中所有参数名。 |
Map | getParameterMap() | 用于将请求中的所有参数名和参数值装入一个 Map 对象中返回。 |
实例:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Map;
@WebServlet(name = "TestServlet", value = "/api/test")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理get请求");
System.out.println("请求的资源:"+ request.getRequestURI());
System.out.println("请求的参数:"+request.getQueryString());
System.out.println("请求的上下文:"+request.getContextPath());
System.out.println("servlet映射的路径:"+request.getServletPath());
System.out.println("客户端地址:"+request.getRemoteAddr());
//设置请求的编码方式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.printf("获取的参数:%s\t%s",username,password);
//获取所有的参数信息
Map<String,String[]> map = request.getParameterMap();
for(String key:map.keySet()){
System.out.printf("%s:%s",key,map.get(key)[0]);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理post请求");
doGet(request,response);
}
}
HttpServletResponse接口是什么?
HttpServletResponse 对象专门用来封装 HTTP 响应消息,简称 response 对象
常用方法:
响应行相关的方法:
返回值类型 | 方法 | 描述 |
---|---|---|
void | setStatus(int status) | 用于设置 HTTP 响应消息的状态码,并生成响应状态行。 |
void | sendError(int sc) | 用于发送表示错误信息的状态码。 |
响应头相关的方法:
返回值类型 | 方法 | 描述 |
---|---|---|
void | addHeader(String name,String value) | 用于增加响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值。 |
void | setHeader (String name,String value) | 用于设置响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值。 |
void | addIntHeader(String name,int value) | 用于增加值为 int 类型的响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值,类型为 int。 |
void | setIntHeader(String name, int value) | 用于设置值为 int 类型的响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值,类型为 int。 |
void | setContentType(String type) | 用于设置 Servlet 输出内容的 MIME 类型以及编码格式。 |
void | setCharacterEncoding(String charset) | 用于设置输出内容使用的字符编码。 |
响应体相关的方法:
返回值类型 | 方法 | 描述 |
---|---|---|
ServletOutputStream | getOutputStream() | 用于获取字节输出流对象。 |
PrintWriter | getWriter() | 用于获取字符输出流对象。 |
注意:getOutputStream() 和 getWriter() 方法互相排斥,不可同时使用,否则会发生 IllegalStateException 异常。
实例:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "TestServlet", value = "/api/test1")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//调用service处理数据
//在页面上输出参数信息
PrintWriter out = response.getWriter();
out.println("<h1>你好啊</h1>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
转发和重定向是什么?
请求转发:
请求转发属于服务器行为。容器接收请求后,Servlet 会先对请求做一些预处理,然后将请求传递给其他 Web 资源,来完成包括生成响应在内的后续工作
RequestDispatcher 对象由 Servlet 容器创建,用于封装由路径所标识的 Web 资源;
利用 RequestDispatcher 对象可以把请求转发给其他的 Web 资源。
Servlet 可以通过 2 种方式获得 RequestDispatcher 对象:
调用 ServletContext 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,必须为绝对路径;
调用 ServletRequest 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,可以为绝对路径,也可以为相对路径
实例:
package com.m0_54698212.servlet;
import com.m0_54698212.entity.Emp;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet(name = "TestServlet", value = "/api/test1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Emp> empList = new ArrayList<>();
empList.add(new Emp("柯基"));
empList.add(new Emp("萨摩耶"));
empList.add(new Emp("二哈"));
request.setAttribute("empList",empList);
//转发,主要拿request里的东西
request.getRequestDispatcher("/test1.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
请求转发的工作原理?
请求转发的特点:
请求转发具有以下特点:
请求转发不支持跨域访问,只能跳转到当前应用中的资源。
请求转发之后,浏览器地址栏中的 URL 不会发生变化,因此浏览器不知道在服务器内部发生了转发行为,更无法得知转发的次数。
参与请求转发的 Web 资源之间共享同一 request 对象和 response 对象。
由于 forward() 方法会先清空 response 缓冲区,因此只有转发到最后一个 Web 资源时,生成的响应才会被发送到客户端
服务器转发:
1、客户端浏览器地址栏并不会发生改变
2、可以实现对request对象中的数据进行共享
3、效率较高,只能在服务器内部转发
request.getRequestDispatcher("/index.jsp").forward(request,response);
客户端重定向:
重定向属于客户端行为。服务器在收到客户端请求后,会通知客户端浏览器重新向另外一个 URL 发送请求,这称为请求重定向。
HttpServletResponse 接口中的 sendRedirect() 方法用于实现重定向:
返回值类型 | 方法 | 描述 |
---|---|---|
void | sendRedirect(String location) | 向浏览器返回状态码为 302 的响应结果,让浏览器访问新的 URL。若指定的 URL 是相对路径,Servlet 容器会将相对路径转换为绝对路径。参数 location 表示重定向的URL |
实例:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet(name = "TestServlet", value = "/api/test1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//客户端重定向
response.sendRedirect("/test1.jsp");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
重定向的工作流程:
转发和重定向的区别?
区别 | 转发 | 重定向 |
---|---|---|
浏览器地址栏 URL 是否发生改变 | 否 | 是 |
是否支持跨域跳转 | 否 | 是 |
请求与响应的次数 | 一次请求和一次响应 | 两次请求和两次响应 |
是否共享 request 对象和 response 对象 | 是 | 否 |
是否能通过 request 域对象传递数据 | 是 | 否 |
速度 | 相对要快 | 相对要慢 |
行为类型 | 服务器行为 | 客户端行为 |