学完之后学习JavaWeb零基础入门之JSP
视频链接:https://www.bilibili.com/video/BV1Y7411K7zz?p=1
参考手册:https://www.w3school.com.cn/html5/index.asp
编写一个类实现Servlet接口,并重写service方法处理请求、响应数据
在WEB-INF文件夹中的web.xml文件中配置Servlet程序的访问地址
代码演示:
新建一个module,选择Java Enterprise➡️Web Application➡️选取适合的服务器
在src下创建一个Hello Servlet类
public class HelloServlet implements Servlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("TestServlet被访问了!");
}
}
在web.xml中的配置
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
web-app>
运行结果:
Servlet程序被访问以后按以下顺序执行:
代码演示:1. 在src目录下创建此类
public class HelloServlet implements Servlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//转换的原因:HttpServletRequest有getMethod方法,可以得到请求的类型
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
//method值为GET或POST,取决于表单提交的method
if (method.equals("POST")){
System.out.println("POST方式");
} else if (method.equals("GET")) {
System.out.println("GET方式");
}
}
代码演示:2. 在web目录下创建Test.html页面
<body>
<form action="http://localhost:8080/servlet/hello" method="post">
<input type="submit">
form>
body>
在实际的项目开发中,都是使用继承HttpServlet类实现Servlet程序的方式,步骤如下:
代码演示:
在src目录下创建此类
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法执行");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost方法执行");
}
}
//HttpServlet的service方法会根据method方式调用二者之一
在web.xml中继续写配置
<servlet>
<servlet-name>HelloServlet2servlet-name>
<servlet-class>com.servlet.HelloServlet2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServlet2servlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
在web中创建Test.html页面
<body>
<form action="http://localhost:8080/servlet/hello2" method="post">
<input type="submit">
form>
body>
运行结果:服务器启动之后,在浏览器的地址栏中的后缀加上Test.html,即可访问此页面,点击提交标签, 即可跳转到http://localhost:8080/MyTest/Test2,执行service方法,进而执行doPost方法
从名字来看,得知此接口中是Servlet程序的配置信息:
ServletConfig接口的三大作用:
代码演示:在web.xml中继续写配置(写在标签中)
<servlet>
<servlet-name>TestServlet4servlet-name>
<servlet-class>com.qizegao.servlet.TestServlet4servlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
init-param>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql:localhost:3306/testparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>TestServlet4servlet-name>
<url-pattern>/Test4url-pattern>
servlet-mapping>
代码演示:在src目录下创建此类
public class TestServlet4 extends HttpServlet {
@Override //使用init方法的原因:1.一定会执行 2.参数中有ServletConfig对象
public void init(ServletConfig config) throws ServletException {
super.init(config);
//1.获取Servlet程序的别名
System.out.println("此程序的别名是:" + config.getServletName());
//2.获取初始化参数init-param,该方法获取指定的参数名的值
System.out.println("初始化参数username的值是:" + config.getInitParameter("username"));
System.out.println("初始化参数url的值是:" + config.getInitParameter("url"));
//3.获取ServletContext对象
System.out.println(config.getServletContext());
}
/*运行结果(浏览器地址栏输入http://localhost:8080/MyTest/Test4):
此程序的别名是:TestServlet4
初始化参数username的值是:root
初始化参数url的值是:jdbc:mysql:localhost:3306/test
org.apache.catalina.core.ApplicationContextFacade@64d62c61 */
}
注意:重写init方法时,必须要在函数体内写:super.init(config);
原因:父类GenericServlet中的init方法将参数config保存起来,子类若不调用则无法保存
ServletContext接口表示Servlet上下文对象
一个web工程只有一个ServletContext对象实例
ServletContext是在web工程启动时创建,在web工程停止时销毁
ServletContext对象是一个域对象
域对象:像Map一样存取数据的对象称为域对象,域指的是存取数据的操作范围,
ServletContext的域是整个web工程
ServletContext接口的四个作用:
代码演示:在web.xml中继续写配置(在标签中)
<context-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
context-param>
<context-param>
<param-name>passwordparam-name>
<param-value>rootparam-value>
context-param>
代码演示:在src目录下创建此类
public class MyContextServlet extends HttpServlet {
//默认执行doGet方法,故只重写doGet方法
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//GenericServlet类中有public ServletConfig getServletConfig()方法,返回this.config
ServletContext servletContext = getServletConfig().getServletContext();
//1.获取web.xml中配置的上下文参数标签中的值
String username = servletContext.getInitParameter("username");
System.out.println("context-param参数的username值是" + username);
/* 运行结果:context-param参数的username值是root */
System.out.println("context-param参数的password值是" + servletContext.getInitParameter("password"));
/* 运行结果:context-param参数的password值是root */
//2.获取当前工程的路径
System.out.println("当前工程路径:" + servletContext.getContextPath());
/* 运行结果:当前工程路径:/MyTest */
//3.获取工程部署后在硬盘上的绝对路径
/* /斜杠(默认路径)对应IDEA代码的web目录 */
System.out.println("工程部署的路径是:" + servletContext.getRealPath("/"));
//在web目录下创建一个css文件夹
System.out.println("工程下css目录的绝对路径是:" + servletContext.getRealPath("/css"));
//在web目录下创建一个img文件夹,里面放1.gif文件
System.out.println("工程下img目录1.gif的绝对路径是:" + servletContext.getRealPath("/img/1.gif"));
}
}
//记得要在浏览器的地址栏输入http://localhost:8080/servlet/MyContextServlet才可访问到此类
代码演示:在src中创建此类,并在web.xml中写对应的配置信息
public class Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//GenericServlet类中有public ServletContext getServletContext()方法,return this.getServletConfig().getServletContext();
ServletContext servletContext = getServletContext();
System.out.println(servletContext);
/* 输出:org.apache.catalina.core.ApplicationContextFacade@2711c490 */
servletContext.setAttribute("key1","value1");
System.out.println(servletContext.getAttribute("key1"));
/* 输出:value1 */
}
}
注意:一个web工程只会创建一个ServletContext对象实例,换其他类输出servletContext得到的结果与上述相同,且一旦给此对象赋值,即使换另一个类getAttribute(key1),得到的结果也是value1
所谓协议指的是双方或多方相互约定好,都要遵守的规则,而HTTP协议指的是客户端和服务器之间通信时发送的数据需要遵守的规则,HTTP协议中的数据又称为报文
请求行:
请求头:
请求头(仅分析与GET请求的不同之处):
MIME是HTTP协议中的数据类型,格式是:大类型/小类型,并与某一种文件的扩展名相对应:
序号 | 内容类型 | 文件类型 | 说明 |
---|---|---|---|
1 | application/msword | doc dot | Microsoft Word2003 |
2 | application/vnd.ms-excel | xIs | Microsoft Excel2003 |
4 | application/vnd.ms-powerpoint | ppt | Microsoft Powerpoint |
5 | application/pdf | Adobe Acrobat | |
6 | application/octet- -stream | bin exe so dll class | 可执行程序 |
6 | application/zip | zip | winzip |
7 | application/x-gzip | gz | gzip |
8 | image/gif | gif | GIF图像 |
9 | image/jpeg | jpg jpeg jpe | JPEG图像 |
10 | image/png | png | PNG图像 |
11 | text/html | html jsp | 网页文档 |
12 2 | text/plain | txt | 文本文档 |
13 | text/xml | xml | XML文档 |
14 | text/json | json | JSON字符串 |
注意点:
HttpServletRequest类的作用:
HttpServletRequest类的常用方法:
代码示例(在src下创建此类):
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取请求的资源路径
String requestURI = request.getRequestURI();
//2.获取请求的绝对路径
StringBuffer requestURL = request.getRequestURL();
//3.获取客户端的ip地址
String requestRemoteHost = request.getRemoteHost();
//4.获取请求头
String requestHeader = request.getHeader("User-Agent");
//5.获取请求的方式
String requestMethod = request.getMethod();
//输出
System.out.println("requestURI => " + requestURI); /* /MyTest/RequestAPI */
System.out.println("requestURL => " + requestURL); /* http://localhost:8080/MyTest/RequestAPI */
System.out.println("请求头 => " + requestHeader); //Mozilla/5.0 (Windows NT 10.0; Win64; x64)...
System.out.println("请求方式 => " + requestMethod); //GET
System.out.println("客户端IP地址 => " + requestRemoteHost); //127.0.0.1
/*在IDEA中,使用localhost访问时得到的客户端ip地址是127.0.0.1
使用127.0.0.1访问时,得到的客户端ip地址是127.0.0.1
使用真实ip访问时,得到的客户端地址是真实的客户端ip地址*/
}
}
获取请求参数
代码示例:
在web目录下创建form.html页面(不可在WEB-INF中创建,无法访问到):
<html lang="en">
<head>
<meta charset="UTF-8">
<title>formtitle>
head>
<body>
<form action="http://localhost:8080/07_servlet/parameterServlet" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="Java">Java
<input type="checkbox" name="hobby" value="JS">JavaScript<br/>
<input type="submit">
form>
body>
html>
在src下创建此类
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//doPost方法会出现中文请求乱码问题
//需要在获取任何参数之前修改字符编码集,而不仅仅获取中文参数时才修改:
request.setCharacterEncoding("UTF-8");
//获取请求的参数(此方法参数中放name属性值,得到value属性值)
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取请求的参数的多个值
String[] hobbies = request.getParameterValues("hobby");
//输出
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
//将数组转换为集合输出
System.out.println("兴趣爱好:" + Arrays.asList(hobbies));
}
}
运行结果:
代码示例:
在src下创建此类,并在web.xml中配置相应的数据
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数(查看办事的材料)
String username = request.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
//给材料盖章
request.setAttribute("key1","柜台1的章");
//获得通向Servlet2的路径(请求转发对象)
//参数必须以斜杠打头,斜杠代表http://localhost:8080/工程名/,对应IDEA代码的web目录
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet2");
//可以转发到WEB-INF目录下:request.getRequestDispatcher("/WEB-INF/xxx");
//通过得到的路径走向Servlet2(柜台2)
//forward方法将当前资源的request和response转发到该requestDispatcher指定的资源
requestDispatcher.forward(request, response);
//使得Servlet2中的request和response与Servlet1一致
}
}
在src下创建此类,并在web.xml中配置相应的数据
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数(查看办事的材料)
String username = request.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
//查看是否有柜台1的章
Object key1 = request.getAttribute("key1");
System.out.println("柜台1的章为:" + key1);
//出处理自己的业务
System.out.println("Servlet2处理业务");
}
}
运行结果:(在浏览器的地址栏中输入:http://localhost:8080/07_servlet/Servlet1?username=jaychou)
可以得出地址栏的内容不发生变化,但页面自动跳转(访问)到了请求转发对象Servlet2中,即显示http://localhost:8080/07_servlet/Servlet2的页面
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base href="http://localhost:8080/MyTest/a/b/">
head>
<body>
这是a下的b下的c.html<br/>
<a href="../../index.html">跳到web下的index.htmla>
body>
斜杠
/servlet1
HttpServletResponse类的作用:
每次只要有请求进入Tomcat服务器,Tomcat服务器就会创建一个Response对象传递给Servlet程序。HttpServletResponse表示所有响应的信息(HttpServletRequest表示请求发来的信息),可以通过HttpServletResponse对象设置返回给客户端的信息
两个输出流的说明:
从服务器往客户端(浏览器)回传字符串数据
代码示例:在src下创建此类并在web.xml中进行配置
public class ResponseIO extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//防止中文乱码问题,在获取流对象之前调用此方法:
//同时设置服务器和客户端都使用UTF-8字符集
response.setContentType("text/html; charset=UTF-8");
//获取流对象
PrintWriter writer = response.getWriter();
writer.write("I Love China!");
}
}
请求重定向指的是客户端给服务器发送请求,然后服务器通知客户端去访问自己的新地址(之前的地址可能被废弃)叫请求重定向
代码示例:
在src下创建此类并在web.xml中进行配置
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("会访问到Response1");
//1.设置响应状态码302
response.setStatus(302);
//2.设置响应头说明新的地址在哪里
response.setHeader("Location","http://localhost:8080/MyTest/Response2");
}
}
在src下创建此类并在web.xml中进行配置
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Response2's result!");
}
}
运行结果:在地址栏输入http://localhost:8080/07_servlet/Response1,得到:
并在控制台输出:会访问到Response1
注意: