0
点赞
收藏
分享

微信扫一扫

JavaWeb_Servlet

guanguans 2022-02-27 阅读 25

一.Servlet技术

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

第一个Servlet程序

  1. 创建HelloServlet类
package com.atguigu.servlet;
import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet{

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /*service方法专门用来处理请求和响应*/
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello Servlet 被访问了");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
  1. 修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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标签给Tomcat配置Servlet程序-->
    <servlet>
        <!--servlet-name标签给程序起一个别名(一般为类名)-->
        <servlet-name>HelloServlet</servlet-name>
        <!--servlet-class是Servlet程序的全类名-->
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--servlet-mapping标签给servlet程序配置访问地址-->
    <servlet-mapping>
        <!--servlet-name标签告诉服务器,当前配置的地址是给哪个Servlet程序使用-->
        <servlet-name>HelloServlet</servlet-name>
        <!--url-pattern配置访问地址-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>
  1. 运行


在 http://localhst:8080/工程名 后加入/hello
控制台输出 Hello Servlet 被访问了

二.Servlet生命周期

三.Servlet表单数据

很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。

1.GET和POST的请求分发处理

  • GET方法:
    GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。
    这些信息使用 QUERY_STRING 头传递,并可以通过 QUERY_STRING 环境变量访问,Servlet 使用 doGet() 方法处理这种类型的请求。
  • POST方法:
    另一个向后台程序传递信息的比较可靠的方法是 POST 方法。POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。Servlet 使用 doPost() 方法处理这种类型的请求。
/*service方法专门用来处理请求和响应*/
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello Servlet 被访问了");

        // 类型转换(因为它有getMethod()方法)
        HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
        // 获取请求方式
        String method =httpServletRequest.getMethod();
        if ("GET".equals(method)){
            // doGet();
        }else if("POST".equals(method)){
            // doPost();
        }
    }

2.继承HttpServlet类

package com.atguigu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

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方法");
    }
}

3.IDEA快速创建Servlet

包 -> New -> Servlet
没有Servlet的话打开项目结构的Facets勾选Source Root

四.Servlet继承体系

  • Servlet接口负责定义Servlet程序的访问规范
  • GenericServlet类实现了Servlet接口,做了很多空实现,并持有一个ServletConfig类的引用,并对其的使用做了一些方法
  • HttpServlet类实现了service方法,并实现了请求的分发处理

1.ServletConfig类

Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。
Servlet程序默认是第一次访问的时候创建,ServletcConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象

@Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("HelloServlet的别名:"+servletConfig.getServletName());
        // HelloServlet的别名:HelloServlet
        System.out.println("初始化参数username的值:"+servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值:"+servletConfig.getInitParameter("url"));
        // 初始化参数username的值:root
        // 初始化参数url的值:jdbc://localhost:3306/test
        System.out.println(servletConfig.getServletContext());
        // org.apache.catalina.core.ApplicationContextFacade@56e41fc7
    }
    <servlet>

        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
        <!--<init-param>初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc://localhost:3306/test</param-value>
        </init-param>
        
    </servlet>

注意:extends HttpServlet时,若重写init方法,必须super.init(config);

2.ServletContext类

  • 四个常见作用

五.HTTP协议

HTTP 协议一般指 HTTP(超文本传输协议)。

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的 WWW 文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

1.的HTTP协议格式

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成

常见的请求头:

2.GET和POST请求的使用

3.响应的HTTP协议

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

常见响应码

4.MIME类型说明

MIME是HTTP协议中数据类型
HTTP content-type 对照表

六.HttpServletRquest类

作用:每次只要有Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法中给我们使用,我们可以通过HttpServletRquest对象,获取到所有请求的信息。

常用方法:

  • getRequestURI() - 该方法用于获取请求的资源路径
  • getRequestURL() - 该方法用于获取请求的统一资源定位符(绝对路径)
  • getRemoteHost() - 该方法用于获取请求客户端的完整主机名,其格式类似于pcl.mengma.com。需要注意的是,如果无法解析出客户机的完整主机名,那么该方法将会返回客户端的 IP 地址。
  • getHeader(String name) - 该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,则getHeader() 方法返回 null;如果请求消息中包含多个指定名称的头字段,则 getHeader() 方法返回其中第一个头字段的值。
  • getParameter() - 获取请求的参数
  • getParameterValues() - 获取请求的参数(多个值的时候使用)
  • getMethod() - 该方法用于获取 HTTP 请求消息中的请求方式(如 GET、POST 等)
  • setAttribute(key,value) - 设置域数据
  • getAttribute(key) - 获取域数据
  • getRequestDispatcher() - 获取请求转发对象

1.获取请求的参数值

form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/servlet_war_exploded/parameterServlet" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" 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>

ParameterServlet.java

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求的参数
        System.out.println("用户名:"+req.getParameter("username"));
        System.out.println("密码:"+req.getParameter("password"));
        String[] hobby=req.getParameterValues("hobby"); // 多个参数
        System.out.println("兴趣爱好:"+ Arrays.asList(hobby));
    }
}

输出:

  • POST请求中文乱码问题
    如果使用doPost方法,则会出现中文乱码问题
req.setCharacterEncoding("UTF-8"); // 在获取所有请求之前调用

使用上述代码后问题解决

2.请求的转发

Servlet1.java

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("柜台1 中查看参数"+req.getParameter("username"));

        req.setAttribute("key","柜台1的章");

        //请求转发必须要以斜杠打头
        RequestDispatcher requestDispatcher=req.getRequestDispatcher("/servlet2");
        requestDispatcher.forward(req,resp);
    }
}

Servlet2,java

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("柜台2 中查看参数"+req.getParameter("username"));

        Object key = req.getAttribute("key");
        System.out.println("柜台1 是否有章"+key);

        System.out.println("Servlet2处理自己的业务");
    }
}

访问:http://localhost:8080/servlet_war_exploded/servlet1?username=zzz
输出:

3.Servlet-base标签

base标签可以设置当前页面中所有相对路径工作时,参照哪个路径进行跳转
请求转发:
ForwardC.java

public class ForwardC extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
    }
}

web/a/b/c.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>c</title>
    <base href="http://localhost:8080/servlet_war_exploded/a/b/c">
</head>
<body>
    这是a下的b下的c.html页面 <br>
    <a href="../../index.html">回到首页</a>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    这是Web下的index.html <br>
    <a href="a/b/c.html">c.html</a><br>
    <a href="http://localhost:8080/servlet_war_exploded/forwardC">请求转发:a/b/c.html</a>
</body>
</html>
  • web中斜杠的不同意义

特殊情况:
response.senRediect("/"); 把斜杠发送给浏览器解析,得到http://ip:port/

七.HttpServletResponse类

每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过Response对象设置。

1.两个输出流

字节流,常用于传递二进制数据
字符流,常用于回传字符串
两个流同时只能使用一个,否则就会报错。

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter();   // 字符流
        resp.getOutputStream(); // 字节流
    }

2.客户端回传字符串数据

方法一:

public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8"); // 服务器中文编码

        resp.setHeader("Content-Type","text/html;Charset=UTF-8");   // 通过响应头设置浏览器也使用UTF-8

        PrintWriter writer=resp.getWriter();
        writer.write("先生请出山");
    }
}

方法二:

resp.setContentType("text/html;charset=UTF-8"); 
// 同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头

注意:此方法一定要在获取流对象之前调用才有效

3.请求重定向

客户端给服务器发请求,服务器告诉客户端,我给你一个新地址,你去新地址访问(因为之前的地址可能已经被废弃)。

特点:
1.浏览器地址栏会发生变化
2.两次请求
3.不共享Request域中的数据
4.不能访问WEB-INF下的资源
5.可以访问工程外的资源
实现方法一:

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("到此一游 Response1");
        // 设置响应状态码302
        resp.setStatus(302);
        resp.setHeader("Location","http://localhost:8080/servlet_war_exploded/response2");
    }
}
public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("response's result!");
    }
}

实现方法二:

resp.sendRedirect("http://localhost:8080/servlet_war_exploded/response2");
举报

相关推荐

0 条评论