一、Servlet

1.1 Servlet简介

  • Servlet就是sun公司开发动态web的一门技术
  • sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    1.编写一个类,实现Servlet接口
    2。把开发好的Java类部署到web服务器中。
  • 把实现了Servlet接口的Java程序叫做,Servlet

1.2 Servlet方法介绍

  • 初始化方法,在servlet被创建时执行,只执行一次

void init(ServletConfig config)

  • 提供服务方法,每次Servlet被访问,都会调用该方法

void service(ServletRequest req,ServletResponse res)

  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet

void destory()

  • 获取ServletConfig对象

ServletConfig getServletConfig()

  • 获取Servlet信息

String getServleInfo()

1.3 使用XML的方式配置Servlet

  • Servlet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet

  • java <url-pattern>的配置方式

1.完全路径配置
以/开始 比如:/hello /servlet01.hello
2.目录匹配
以/开始,以/结束 比如:/ /aaa/*
3.扩展名匹配
不能以/开始,以*开始 比如: *.action   *.jsp

步骤:

  1. 编写一个普通的类,继承HtttpServlet

HelloServlet.java

package Servlet01;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		PrintWriter out=resp.getWriter();
		out.print("hello servlet");
	}

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

}

  1. 编写Servlet映射
    (为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们所写的Servlet,还需要给他一个浏览器能够访问的路径)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://java.sun.com/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee" id="WebApp_ID" version="2.4">
  <display-name>test01</display-name>
  
  <!-- servlet标签给Tomcat配置servlet程序 -->
  <servlet>
  <!-- servlet-name标签给Servlet程序起一个别名(一般是类名) -->
  	<servlet-name>HelloServlet</servlet-name>
  	<!-- servlet-class是servlet程序的全类名 -->
  	<servlet-class>Servlet01.HelloServlet</servlet-class>
  </servlet>
  
  <!-- servlet-mapping标签给servlet程序配置访问地址 -->
  <servlet-mapping>
 	<!-- servlet-name标签的作用是告诉服务器,我当前配置的地址给哪一个servlet程序使用 -->
  	<servlet-name>HelloServlet</servlet-name>
  	<!-- url-pattern标签配置访问地址
  	 / 斜杠在服务器解析的时候,表示http://ip:port/工程路径
  	 /hello  表示地址为http://ip:port/工程路径/hello
  	 -->
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>
  
</web-app>
  • 访问路径
    http://localhost:8080/test01/hello
    在这里插入图片描述

  • 结果图
    在这里插入图片描述

1.4 使用注解的方式配置Servlet

方式:@WebServlet("/demo01")

ServlertDemo01.java

package Servlet02;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/demo01")
public class ServlertDemo01 extends HttpServlet  {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out=resp.getWriter();
		out.print("hello 注解的方式配置servlet");
				![在这里插入图片描述](https://img-blog.csdnimg.cn/a2d1ba0b85044adbb2b2597df83e35a8.png#pic_center)

	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
}

结果图

在这里插入图片描述

1.5 Mapping问题

  1. 一个servlet可以指定一个映射路径
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
  1. 一个servlet可以指定多个映射路径
<!--Servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello1</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello2</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello3</url-pattern>
  </servlet-mapping>
  1. 一个servlet可以指定多个映射路径
<!--Servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>
  1. 默认请求路径
<!--Servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  1. 指定一些后缀或前缀等等…
<!--Servlet的请求路径-->
  <servlet-mapping>
    <!--可以自定义后缀实现请求映射
    注意点:*前面不能加项目映射的路径(斜杠)
    -->
    <servlet-name>hello</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  1. 优先级问题
    指定了固有的映射路径优先级最高,如果找不到就走默认的处理请求。

1.6 ServletContext

web容器在启动的时候,它会为每一个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

1.6.1 共享数据

我在这个servlet中保存的数据,可以在另外一个servlet中拿到:

保存数据的servlet

package com.yan.study;

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

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getInitParameter()  初始化参数
        //this.getServletConfig()   servlet配置
        //this.getServletContext()    servlet上下文

        ServletContext context=this.getServletContext();
        String uname="小言";
        context.setAttribute("username",uname);//将一个数据保存在ServletContext中,名字为:username,值为uname
    }
}

获取数据的servlet(GetServlet)

package com.yan.study;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String username=(String) context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字:"+username);
    }
}

配置servlet的XML

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.yan.study.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>get</servlet-name>
    <servlet-class>com.yan.study.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>get</servlet-name>
    <url-pattern>/get</url-pattern>
  </servlet-mapping>

</web-app>

测试结果图

在这里插入图片描述

1.6.2 获取初始化参数

配置XML

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置一些web应用初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>

  <servlet>
    <servlet-name>gp</servlet-name>
    <servlet-class>study.ServletDemo03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gp</servlet-name>
    <url-pattern>/gp</url-pattern>
  </servlet-mapping>
</web-app>

ServletDemo03

package study;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String url=context.getInitParameter("url");
        resp.getWriter().print(url);
    }
}

测试结果

在这里插入图片描述

1.6.3 请求转发

  • 写一个ServletDemo04转发到ServletDemo03里面

ServletDemo04

package study;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        ServletContext context=this.getServletContext();
        System.out.println("进入了ServletDemo04");
        RequestDispatcher requestDispatcher=context.getRequestDispatcher("/gp");//转发的请求路径
        requestDispatcher.forward(req,resp);//调用forward实现请求转发
    }
}

配置xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置一些web应用初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>

  <servlet>
    <servlet-name>gp</servlet-name>
    <servlet-class>study.ServletDemo03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gp</servlet-name>
    <url-pattern>/gp</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>demo04</servlet-name>
    <servlet-class>study.ServletDemo04</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>demo04</servlet-name>
    <url-pattern>/demo04</url-pattern>
  </servlet-mapping>

</web-app>

测试结果

在这里插入图片描述

1.7 HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

重定向 [resp.sendRedirect();]

  • 在访问RedirectServlet时,重定向到GetServlet

RedirectServlet

package com.yan.study;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/servlet01_war/get");
    }

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

    }
}

配置XML

<servlet>
    <servlet-name>red</servlet-name>
    <servlet-class>com.yan.study.RedirectServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>red</servlet-name>
    <url-pattern>/red</url-pattern>
  </servlet-mapping>

结果图展示
在这里插入图片描述

重定向和转发的区别?

相同点:页面都会实现跳转
不同点:
请求转发的时候,url不会发生变化
重定向的时候,url地址会发生变化

1.8 HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法,获得客户端的所有信息。

1.8.1 获取参数,请求转发

  • RequestDemo01一个servlet,从form.jsp的表单中获取信息,重定向到success.jsp中

form.jsp


<%--<%@ page contentType="text/html;charset=UTF-8" language="java" %>--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--${pageContext.request.contextPath}代表当前项目--%>
<form action="${pageContext.request.contextPath}/demo01" method="get">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit">
</form>

</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>

ResquestDemo01

package com.yan.study;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet(urlPatterns = "/demo01")
public class RequestDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname=req.getParameter("username");
        String psw=req.getParameter("password");
        System.out.println(uname+";"+psw);
        resp.sendRedirect("/test01_war/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

结果图展示(第一张图是form.js运行的结果,第二张图是重定向到success.jsp的结果图)

图一:图一
图二:在这里插入图片描述

二、Cookie、Session

  • 会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。

保存会话的两种技术

  • cookie
    客户端技术(响应,请求)
  • session
    服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者是数据放在session中。

2.1 Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
Cookie[] cookies =req.getCookies();//获得cookie
cookie.getName(); //获得cookie的key
cookie.getValue(); //获得cookie的value
Cookie cookie= new Cookie("name","value"); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie

2.2 Session

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个session对象;
  • 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在;
  • 用户登录之后,整个网站都可以访问。(保存用户的信息)

Session和cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
  • Session把用户的数据写到用户独占Session中,服务器端中保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建。

使用session

package com.yan.study;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;

@WebServlet(urlPatterns = "/sd")
public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        resp.setContentType("text/html");
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //得到session
        HttpSession session= req.getSession();

        //给session中存东西
        session.setAttribute("name",new Person("小言",20));

        //获取session的ID
        String id=session.getId();

        //判断Session是不是新创建的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+id);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:"+id);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

会话自动过期:web.xml配置

<!--设置session默认的实效时间-->
  <session-config>
    <!--  15分钟后,session自动实效,以分钟为单位-->
    <session-timeout>15</session-timeout>
  </session-config>

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐