Servlet 的三种创建方式、请求响应常用方法

Servlet 的三种创建方式、请求响应常用方法

目录Servlet1. Servlet 的三种创建方式1.1 Servlet 程序的整体代码逻辑结构1.2 遵从 Servlet 接口实现 Servlet 程序1.3 继承 GenericServlet 抽象类实现 Servlet 程序1.4 继承 HttpServlet 抽象类实现 Servlet 程序1.5 三种方式对比和结构分析2. 请求响应常用方法2.1 ServletRequest 常用方法2.2 ServletRequest 重要方法【VIP Method】2.3 ServletResponse 常用方法3. Servlet 案例3.1 前端提交数据到后台,后台保存到数据库

Servlet

1. Servlet 的三种创建方式

1.1 Servlet 程序的整体代码逻辑结构

interface Servlet

Java EE 规范规定的 Servlet 程序必须要求完成的方法,整个 Java WEB 中所有 servlet 程序的总接口。

abstract class GenericServlet implements Servlet, ServletConfig

完成了一部分 Servlet 接口规范的 abstract 修饰类,同时引入了 ServletConfig 规则、

abstract class HttpServlet extends GenericServlet

引入了 HTTP 协议,符合 Servlet 标准的一个 abstract 修饰类

自定义类【遵从】 servlet 接口,请问算不算一个 Servlet 程序???

算!!!

自定义类【继承】 GenericServlet 抽象类,请问算不算一个 Servlet 程序???

算!!!

1.2 遵从 Servlet 接口实现 Servlet 程序

package com.qfedu.a_createServlet;

import javax.servlet.*;

import javax.servlet.annotation.WebServlet;

import java.io.IOException;

/**

* 遵从 Servlet 接口实现 Servlet 程序

*

* public void init(ServletConfig config) throws ServletException

* 初始化当前 Servlet 程序,所需参数是 ServletConfig 对象 servlet 配置对象

*

* public ServletConfig getServletConfig()

* 获取 ServletConfig Servlet配置对象,可以认为 ServletConfig 是 Servlet 程序的一部分

*

* public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException

* 【核心方法】

* 对外提供数据服务的方法,所需参数是 Tomcat 在处理用户请求时对应创建的 ServletRequest 和 绑定的

* ServletResponse 对象

*

* public String getServletInfo()

* 获取 Servlet 字符串描述信息

*

* public void destroy()

* 销毁 Servlet 程序,Tomcat退出时自动调用

* 业务逻辑考虑

* 用户登陆 ==> 对应当前用户的 servlet 启动提供服务

* 用户退出 ==> 对应当前用户的 servlet 调用 destroy 销毁

*

* @author Anonymous 2022/4/15 9:33

*/

@WebServlet("/cs1")

public class CreateServlet1 implements Servlet {

public CreateServlet1() {

System.out.println("CreateServlet1 Constructor called...");

}

@Override

public void init(ServletConfig config) throws ServletException {

System.out.println("init method called...");

}

@Override

public ServletConfig getServletConfig() {

System.out.println("getServletConfig method called...");

return null;

}

@Override

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

System.out.println("Service method called...");

/*

HttpServletRequest HttpServletResponse

在原始的 ServletRequest ServletResponse 做了增强,满足适应 Http 协议规范!!!

*/

res.getWriter().append("

Implements Interface Servlet to Create Servlet Program

");

}

@Override

public String getServletInfo() {

System.out.println("getServletInfo method called...");

return null;

}

@Override

public void destroy() {

System.out.println("destroy method called...");

}

}

1.3 继承 GenericServlet 抽象类实现 Servlet 程序

package com.qfedu.a_createServlet;

import javax.servlet.GenericServlet;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.annotation.WebServlet;

import java.io.IOException;

/**

* 继承 abstract class GenericServlet

*

* public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException

* 有且只需要实现 service 方法,因为其他 Servlet 接口中规定的方法,全部都已经实现。

* 程序员在完成 Servlet 程序的过程中,更加专注的是业务逻辑相关内容

*

* Servlet 接口使用一个手动挡

* 开车需要考虑离合,换挡,油门,刹车...

* GenericServlet 抽象类是一个自动挡

* 只需要考虑 D 挡,油门,刹车,专注于开车!!!

* @author Anonymous 2022/4/15 9:33

*/

@WebServlet("/cs2")

public class CreateServlet2 extends GenericServlet {

@Override

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

System.out.println("Service method called...");

/*

HttpServletRequest HttpServletResponse

在原始的 ServletRequest ServletResponse 做了增强,满足适应 Http 协议规范!!!

*/

res.getWriter().append("

Extend abstract class GenericServlet to Create Servlet Program

");

}

}

1.4 继承 HttpServlet 抽象类实现 Servlet 程序

package com.qfedu.a_createServlet;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

* 继承 abstract class HttpServlet 完成 Servlet

*

* 继承之后虽然 HttpServlet 是一个 abstract 修饰类,但是没有任何一个强制方法需要实现

* 在 HttpServlet 中继承 GenericServlet ,实现了 符合 Servlet 接口规范的 service 方法

* 并且增强 service 方法,加入 HTTP 协议,按照 HTTP 协议规范根据用户请求的方式操作实现

* 对应处理方法

* doGet ==> GET 请求

* doPOST ==> POST 请求

* 程序员无需考虑 Servlet 整体的实现过程,初始化方法,资源销毁,数据配置,而且专注于

* 针对用户请求数据方式的处理过程。

*

* 自动挡汽车

* 不同的驾驶模式,有自动辅助驾驶。

*

* @author Anonymous 2022/4/15 9:33

*/

@WebServlet("/cs3")

public class CreateServlet3 extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.getWriter().append("

Extend abstract class HttpServlet to Create Servlet Program

");

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

1.5 三种方式对比和结构分析

Servlet 接口规定了 Java EE 规范所有 Servlet 程序必须完成的方法内容,涉及到 Servlet 初始化,销毁,配置,数据信息获取,和【服务方法】,只考虑业务逻辑,需要完成的方法过多,使用不便。并且不支持 HTTP 协议

GenericServlet 遵从 Servlet 接口,将和业务逻辑无关的方法内容,完成配套实现,留给用户的有且只有 service 方法,作为业务逻辑的实现。

HttpServlet 继承 GenericServlet 引入 HTTP 协议支持,针对于不同的 HTTP 请求方式分门别类处理,同时引入了 HTTP 协议的其他规范,例如 Cookie Session Header... 对于用户而言可以专注于请求方式对应业务逻辑处理。

abstract 类在代码结构中【承上启下】

2. 请求响应常用方法

2.1 ServletRequest 常用方法

方法名

功能

String getMethod();

获取当前用户请求方式 GET or POST

String getRequestURL();

获取用户请求完整 URL http://localhost:8080/Day38/test

String getRequestURI();

获取用户请求资源信息 /Day38/test

String getQueryString();

GET请求生效,可以获取URL参数 name=James&age=16

String getProtocol();

获取当前请求的协议类型 HTTP/1.1

String getRemoteAddr();

获取用户主机 IP 地址

String getRemoteHost();

获取用户请求目标主机地址/域名/IP地址

int getRemotePort();

请求资源的端口号

String getRemoteUser();

请求对应的用户名

String getContextPath();

获取虚拟路径名称 http://localhost:8080/Day38/test == /Day38

String getHeader(String headerName)

根据请求头的名称获取对应数据

setCharacterEncoding();

请求数据编码集修改,可以处理乱码问题

package com.qfedu.b_method;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.ArrayList;

/**

* 演示 Request 常用方法

*

*

*

* @author Anonymous 2022/4/15 11:28

*/

@WebServlet("/rm1")

public class RequestMethod1 extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// 获取当前用户请求方式 GET or POST

String method = req.getMethod();

System.out.println("用户当前请求方式 : " + method);

// 获取用户请求完整 URL

StringBuffer requestUrl = req.getRequestURL();

System.out.println("获取用户请求完整 URL : " + requestUrl);

// 获取用户请求资源信息

String requestUri = req.getRequestURI();

System.out.println("获取用户请求资源信息 : " + requestUri);

// GET请求生效,可以获取URL参数 name=James&age=16

String queryString = req.getQueryString();

System.out.println("用户通过 GET 请求提交的参数字符串 : " + queryString);

// 获取当前请求的协议类型 HTTP/1.1

String protocol = req.getProtocol();

System.out.println("获取当前请求的协议类型 : " + protocol);

// 获取用户主机 IP 地址

String remoteAddr = req.getRemoteAddr();

System.out.println("获取用户主机 IP 地址 : " + remoteAddr);

// 获取用户请求目标主机地址/域名/IP地址

String remoteHost = req.getRemoteHost();

System.out.println("获取用户请求目标主机地址/域名/IP地址 : " + remoteHost);

// 请求资源的端口号

int remotePort = req.getRemotePort();

System.out.println("请求资源的端口号 : " + remotePort);

// 请求对应的用户名

String remoteUser = req.getRemoteUser();

System.out.println("请求对应的用户名 : " + remoteUser);

// 【重点方法】获取虚拟路径名称 http://localhost:8080/Day38/test == /Day38

String contextPath = req.getContextPath();

System.out.println("获取虚拟路径名称 : " + contextPath);

// 根据请求头的名称获取对应数据

String header = req.getHeader("Cache-Control");

System.out.println("Cache-Control header :" + header);

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

2.2 ServletRequest 重要方法【VIP Method】

方法

功能

String getParameter(String name)

根据指定的参数名称获取对应数据,数据类型为 String

String[] getParameterValues(String name);

根据指定的参数名称获取对应数据,数据类型为String[] 字符串数组,可以用于多选框操作

Map getParameterMap();

获取当前 Request 请求中用户提交的所有参数和数据的 Map 双边队列,Map 对应 key 是参数名称 String 类型,参数值 value 为 String[] 【你会用的上瘾】

Enumeration getParameterNames();

获取用户请求数据当中所有参数名称,可以讲Enumeration 看做是一个 Set 集合

// BeanUtils 工具类

BeanUtils.setProperty(Object bean, String name, Object value);

BeanUtils.copyProperties(Object dest, Object src);

String BeanUtils.getProperty(Object bean, String name);

BeanUtils.populate(Object bean, Map properties);

package com.qfedu.b_method;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.Arrays;

import java.util.Enumeration;

import java.util.Map;

/**

*

*

* @author Anonymous 2022/4/15 14:54

*/

@WebServlet("/rm2")

public class RequestMethod2 extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// getParameter 根据指定的参数名称获取对应数据,数据类型为 String

String name = req.getParameter("name");

String age = req.getParameter("age");

String gender = req.getParameter("gender");

// 根据指定的参数名称获取对应数据,数据类型为String[] 字符串数组,可以用于多选框操作

String[] hobbies = req.getParameterValues("hobby");

System.out.println(name);

System.out.println(age);

System.out.println(gender);

System.out.println(Arrays.toString(hobbies));

System.out.println();

// 获取当前 Request 请求中用户提交的所有参数和数据的 Map 双边队列,

// name=王乾&age=80&gender=0&hobby=0&hobby=3 ==>

// Map = {"name"={"王乾"}, "age"={"80"}, "gender"={"0"}, "hobby"={"0", "3"}}

// Map 对应 key 是参数名称 String 类型,参数值 value 为 String[] 【你会用的上瘾】

Map parameterMap = req.getParameterMap();

parameterMap.forEach((key, value) -> System.out.println(key + ":" + Arrays.toString(value)));

System.out.println();

// 获取用户请求数据当中所有参数名称,可以将 Enumeration 看做是一个 Set 集合

// TODO Enumeration

Enumeration parameterNames = req.getParameterNames();

while (parameterNames.hasMoreElements()) {

System.out.println(parameterNames.nextElement());

}

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

2.3 ServletResponse 常用方法

方法

功能

setContentType()

设置当前响应数据类型 setContentType("text/html;charset=utf-8")

PrintWriter getWriter();

获取可以发送数据到前端的【字符流】 PrintWriter 常用 append(String)

package com.qfedu.b_method;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

* @author Anonymous 2022/4/15 15:38

*/

@WebServlet("/respMethod")

public class ResponseMethod extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// "text/html;charset=utf-8"

// 设定当前对外数据形式为可视化文本 HTML 类型数据,编码集采用 UTF-8 中文可见

resp.setContentType("text/html;charset=utf-8");

resp.getWriter().append("

路见不平一声吼,大哥没有男朋友

");

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

3. Servlet 案例

3.1 前端提交数据到后台,后台保存到数据库

注册

姓名 :

年龄 :

性别 :

package com.qfedu.c_demo;

import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.lang.reflect.InvocationTargetException;

import java.util.Map;

/**

* @author Anonymous 2022/4/15 16:14

*/

@WebServlet("/register")

public class RegisterServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

req.setCharacterEncoding("utf-8");

// 直接获取用户提交数据的 Map 双边队列

Map map = req.getParameterMap();

// 实例化 Person 对象

Person person = new Person();

try {

// 利用 BeanUtils 工具类中 populate 方法使用

// map 双边队列给予 JavaBean 规范对象赋值操作

BeanUtils.populate(person, map);

} catch (IllegalAccessException | InvocationTargetException e) {

e.printStackTrace();

}

// 实例化 PersonDao 对象

PersonDao personDao = new PersonDao();

// Person 对象 通过 registerPerson 方法存储到数据库中

if (1 == personDao.registerPerson(person)) {

System.out.println("添加成功");

} else {

System.out.println("添加失败");

}

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

package com.qfedu.c_demo;

import util.BaseDao;

import java.sql.SQLException;

/**

* 业务逻辑相关 Dao 首先继承 BaseDao

*

* @author Anonymous 2022/4/15 16:15

*/

public class PersonDao extends BaseDao {

/**

* 保存 Person 数据到数据中

*

* @param person Person 对象

* @return SQL 语句运行对数据表的影响行数

*/

public int registerPerson(Person person) {

String sql = "insert into javaee_2203.user(name, age, gender) VALUES (?, ?, ?)";

int i = 0;

try {

i = super.update(sql, person.getName(), person.getAge(), person.getGender());

} catch (SQLException e) {

e.printStackTrace();

}

return i;

}

}

相关推荐

龙城霸业
Bet体育365提款流水

龙城霸业

⏱️ 09-25 👁️ 6153
微信群如何签到
Bet体育365提款流水

微信群如何签到

⏱️ 07-18 👁️ 8238
dnf安图恩单人每日攻略 5分钟教你轻松通关
365bet手机娱乐

dnf安图恩单人每日攻略 5分钟教你轻松通关

⏱️ 07-29 👁️ 1712
男人為什麼愛「中出」?蜜穴的包覆讓GG超敏感,男人沉迷中出的原因
人的身體一共有多少個毛孔?
Bet体育365提款流水

人的身體一共有多少個毛孔?

⏱️ 07-28 👁️ 5914
出售二手台式机电脑
365bet手机娱乐

出售二手台式机电脑

⏱️ 07-05 👁️ 5871