前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tomcat和servlet快速入门教程!!!

tomcat和servlet快速入门教程!!!

作者头像
大忽悠爱学习
发布2021-11-15 11:40:44
4110
发布2021-11-15 11:40:44
举报
文章被收录于专栏:c++与qt学习

Tomact和servlet快速入门教程


tomcat的入门必备知识

1.下载:

tomcat官网下载地址

2.安装: 解压压缩包即可

注意:安装目录建议不要有中文和空格

在这里插入图片描述
在这里插入图片描述

3.卸载: 删除目录即可

4.启动:

4.1 bin/startup.bat ,双击运行该文件即可 4.2 访问:浏览器输入: http://localhost:8080 回车访问自己 或者 http://别人的ip:8080 访问别人 可以通过ipconfig:查看本机ip地址

4.3 启动可能出现的问题:

4.3.1 黑窗口一闪而过:

原因: 没有正确配置JAVA_HOME环境变量

4.3.2 启动报错:

原因: 端口号被占用

推荐的解决方法1: 找到占用的端口号,并且找到对应的进行,杀死该进程

在cmd窗口输入netstat -ano

在这里插入图片描述
在这里插入图片描述

打开任务管理器,找到刚才的进程ID,然后结束该进程

在这里插入图片描述
在这里插入图片描述

解决方法2: 修改自身端口号

conf/server.xml用记事本打开,将其默认端口号修改即可,可能还需要连带着修改其他的相关默认端口号才行

在这里插入图片描述
在这里插入图片描述

一般会把tomcat的默认端口号修改为80. 80端口号是http协议的默认端口号 好处:在访问时,就不需要输入端口号了

5.关闭:

强制关闭: 点击窗口的x 正常关闭: bin/shutdown.bat 或者ctrl+c

6.部署:

部署方式: 1.直接将项目放到webapps目录下即可 /hello: 项目的访问路径---->虚拟目录 简化部署:将项目打包成一个war包,再将war包部署到webapps目录下面 war包会自动解压缩.

2.配置conf/server.xml文件 在< Host >标签体中配置

代码语言:javascript
复制
<Context docBase="D:\hello" path="/hehe" />

docBase: 项目存放的路径 path: 虚拟目录

3.在conf\Catalina\localhost创建了一个任意名称的xml文件。 在文件中编写:

代码语言:javascript
复制
<Context docBase="D:\hello"/>

虚拟目录就是xml文件的名称

静态项目和动态项目

目录结构: java动态项目的目录结构: -项目根目录 –WEB-INF目录: — web.xml: web项目的核心配置文件 —classes: 放置字节码文件的目录 —lib目录: 放置依赖的jar包


将tomcat集成到IDEA中,并且创建JavaEE项目,部署项目

tomcat集成到IDEA的教程


Servlet

概念:运行在服务器端的小程序 Servlet就是一个接口,定义了Java类被浏览器访问到的(tomcat)规则 将来我们自定义一个类,实现Servlet接口,复写方法

web动态工程目录介绍

在这里插入图片描述
在这里插入图片描述

热部署

Tomcat上的部署问题,有时候也是个麻烦的问题,要是不采用热部署,我们就只能每次对原来的文件做一次改动的时候就要重新部署,而每次重新部署都要关闭tomcat,部署完重启tomcat,可见这是一个多么烦人的事情。现在,我们可以采用热部署了,以后,就不用做烦人的关闭重起工作。

热部署的设置:

在这里插入图片描述
在这里插入图片描述

快速入门

  1. 创建JavaEE项目
  2. 定义一个类,实现Servlet的接口
  3. 实现接口中的抽象方法
  4. 配置servler

在wed.xml的< web-app >标签里面进行配置:

代码语言:javascript
复制
<?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-->
    <servlet>
        <!--servlet-name标签Servlet程序起一个别名(一般是类名)-->
        <servlet-name>demo1</servlet-name>
        <!--servlet-class是servlet的全类名-->
        <servlet-class>web.servlet.servletDemo</servlet-class>
    </servlet>
    <!--给servlet程序配置访问地址-->
    <servlet-mapping>
        <!--告诉服务器,我当前配置的地址给哪个servlet程序使用-->
        <servlet-name>demo1</servlet-name>
        <!--配置访问地址
           / 斜杠在服务器解析的时候表示地址为: http://ip:port/工程路径
           /demo1 表示地址为:  http://ip:port/工程路径/demo1
        -->
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>

常见错误: url-pattern配置的路径中没有以斜杠打头 servlet-name配置的值不存在 servlet-class标签全类名配置错误

工程路径名修改:

在这里插入图片描述
在这里插入图片描述

URL地址定位实现原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

执行原理: 1.当服务器接收到客户端的请求后,会解析请求URL路径,获取访问的Servlet的资源路径 2.查找web.xml文件,看是否有对应的< url-pattern >标签内容体 3.如果有,则在找到对应的< servlet-class >全类名 4.tomcat会将字节码文件加载进内存,并且创建其对象 5.调用其方法


生命周期方法

servlet中的生命周期:

  1. 被创建: 执行Init方法,只执行一次
  2. 提供服务: 执行service方法,执行多次
  3. 被销毁: 执行destory方法,只执行一次

Servlet的创建时机: 默认情况下,第一次被访问时,Servlet被创建 可以配置执行Sevlet的创建时机,如下:

代码语言:javascript
复制
<?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-->
    <servlet>
        <!--servlet-name标签Servlet程序起一个别名(一般是类名)-->
        <servlet-name>demo1</servlet-name>
        <!--servlet-class是servlet的全类名-->
        <servlet-class>web.servlet.servletDemo</servlet-class>

      <!--  指定Servlet的创建时机
           1.第一次被访问时,创建
            <load-on-startup>的值为负数
            2.在服务器启动时,创建
             <load-on-startup>的值为0或者正整数
      -->
        <load-on-startup>5</load-on-startup>
    </servlet>
    <!--给servlet程序配置访问地址-->
    <servlet-mapping>
        <!--告诉服务器,我当前配置的地址给哪个servlet程序使用-->
        <servlet-name>demo1</servlet-name>
        <!--配置访问地址
           / 斜杠在服务器解析的时候表示地址为: http://ip:port/工程路径
           /demo1 表示地址为:  http://ip:port/工程路径/hello
        -->
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>

Servlet的init方法只执行一次,说明Servlet在内存中只存在一个对象,说明Servlet是单例的

  1. 多个对象同时访问时,可能存在线程安全问题
  2. 解决: 净量不要再Servlet中定义成员变量.即使定义了成员变量也不要修改其值

每次访问Servlet时,service方法都会被调用一次

Servlet被销毁时执行。服务器关闭时,Servlet被销毁。 只有服务器正常关闭时,才会执行destory 销毁方法在对象被销毁前执行


注解配置

Servlet 3.0以上才支持注解配置,支持注解配置后,就不需要web.xml了。

对于web.xml来说,对应的每一个servlet工程都需要重新配置一个web.xml太过繁琐

步骤:

  1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
  2. 定义一个类来实现Servlet的接口
  3. 复写方法
  4. 在类上使用@WebServlet注解,进行配置
在这里插入图片描述
在这里插入图片描述

注解就是加在类上面的,因此不需要关心全类名了,也就不需要再通过name属性做对应关系了

代码语言:javascript
复制
@WebServlet(urlPatterns="资源路径");
简化写法---->注解中最重要的属性value,其实就是urlPatterns属性,因此可以省略value
@WebServlet("资源路径");
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

IDEA与tomcat的相关配置

在这里插入图片描述
在这里插入图片描述

Servlet的体系结构

在这里插入图片描述
在这里插入图片描述

Servlet的urlpattern配置

1. urlpattern:servlet的访问路径

2.一个servlet可以定义多个访问路径: @WebServlet({"/Demo2","/dhy","/ly"})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.路径定义规则:

1. /xxx 2. /xxx/xxx :多层路径,目录结构

在这里插入图片描述
在这里插入图片描述
  1. *.xxx
在这里插入图片描述
在这里插入图片描述

Servlet的url详解


Http

在这里插入图片描述
在这里插入图片描述

Http请求数据格式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Request对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Request对象的继承体系结构

在这里插入图片描述
在这里插入图片描述

Request的功能

获取请求行数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码演示:

代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/RequestServlet")
public class RequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  //1.获取请求方式: GET
        String method=request.getMethod();
        System.out.println(method);
        //2.获取虚拟目录: /demo2
        String contextPath=request.getContextPath();
        System.out.println(contextPath);
        //3.获取servlet路径:/RequestServlet
        String servletPath=request.getServletPath();
        System.out.println(servletPath);
        //4.获取get方式请求参数: name=dhy
        String queryString=request.getQueryString();
        System.out.println(queryString);
        //5.获取请求URI: /demo2/RequestServlet
        String requestURI=request.getRequestURI();
        StringBuffer requestURL=request.getRequestURL();
        System.out.println(requestURI);
        System.out.println(requestURL);
        //6.获取协议及版本: HTTP/1.1
        String  protocol=request.getProtocol();
        System.out.println(protocol);
        //7.获取客户机的IP地址
        String remoteAddr=request.getRemoteAddr();
        System.out.println(remoteAddr);
        
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
在这里插入图片描述
在这里插入图片描述

获取请求头数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

获取所有头名称代码演示:

代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/req")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求头数据
        //1.获取所有请求头名称
        Enumeration<String> headerNames=request.getHeaderNames();
        //2.遍历
        while(headerNames.hasMoreElements())
        {
            String name=headerNames.nextElement();
            //更据名称获取请求头的值
            String header=request.getHeader(name);
            System.out.println(name+"------"+header);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
在这里插入图片描述
在这里插入图片描述

获取浏览器版本相关信息代码演示:

代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/req")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           //演示获取请求头数据: user-agent
        String agent=request.getHeader("user-agent");//不区分大小写

        //判断agent的浏览器版本:
        if(agent.contains("Chrome"))
        {
            System.out.println("当前正在使用的是谷歌浏览器");
        }
        else if(agent.contains("Firefox"))
        {
            System.out.println("当前正在使用火狐浏览器");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
在这里插入图片描述
在这里插入图片描述

告诉服务器请求从哪里来—referer:

代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/req")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           //演示获取请求头数据: user-agent
        //告诉服务器请求当前servlet实例的请求从哪里来的,是否来自指定网址
        String referer=request.getHeader("referer");//不区分大小写
        System.out.println(referer); //  http://localhost:8080/demo2/login.html

      //防止盗链
        if(referer!=null)
        {
            if(referer.contains("/demo2"))
            {
                System.out.println("下面播放极限挑战");
            }
            else//盗链
                System.out.println("请付费支持正版");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

获取请求体数据

在这里插入图片描述
在这里插入图片描述

代码演示:

代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/demo")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体----请求参数

        //1.获取请求字符流
        BufferedReader br=request.getReader();
        //2.读取数据
        String line=null;
        while((line=br.readLine())!=null)
        {
            System.out.println(line);
        }

    }
}

login.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<form action="/demo2/demo" method="post">//action属性:设置表单提交的服务器地址
    <input type="text" placeholder="请输入用户名" name="username"><br>
    <input type="text" placeholder="请输入密码" name="password"><br>
    <input type="submit" value="注册"><br>

</form>
</body>
</html>
在这里插入图片描述
在这里插入图片描述

获取请求参数的通用方式

在这里插入图片描述
在这里插入图片描述
根据参数名获取参数值:
代码语言:javascript
复制
package request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/demo")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //获取get请求参数
        //根据参数名称获取参数值
        String username=request.getParameter("username");
        System.out.println("get方式:");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
      //获取post请求参数
     //根据参数名称获取参数值
/*        String username=request.getParameter("username");
        System.out.println("post方式:");
        System.out.println(username);*/
        //因为doPost方法里面的代码逻辑和doGet方法里面代码逻辑相同,因此可以在doPost方法里面直接调用doGet方法
        //简化代码书写
        doGet(request,response);
    }
}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据参数名称获取参数值数组,多用于复选框:
代码语言:javascript
复制
@WebServlet("/demo")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String[] hobbies=request.getParameterValues("hobby");
        for(String hobby:hobbies)
            System.out.println(hobby);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doGet(request,response);
    }
}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
获取所有请求的参数名称
代码语言:javascript
复制
     Enumeration<String> names= request.getParameterNames();
            while(names.hasMoreElements())
            {
                String name=names.nextElement();
                String value=request.getParameter(name);
                System.out.println(name+":"+value);//对于复选框,如果有多个参数值,那么这里只能获取第一个参数值,除非用数组形式获取
            }
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
获取所有参数的map集合
代码语言:javascript
复制
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for(String value:strings)
        {
            //根据key获取值
            String[] strings1 = parameterMap.get(value);
            for(String s:strings1) {
                System.out.println("key=" + value + "  value=" + s);
            }
        }
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上面的四种方法,第一种和第四种较为常用


请求中的中文乱码问题
  1. tomcat 8已经将get方式乱码解决,如果get方式还是有乱码,去配置中修改
在这里插入图片描述
在这里插入图片描述
  1. post方式中文会乱码
在这里插入图片描述
在这里插入图片描述

解决: 获取参数前,设置request的编码:

代码语言:javascript
复制
 //1.设置流的编码
        request.setCharacterEncoding("utf-8");

代码:

代码语言:javascript
复制
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //1.设置流的编码
        request.setCharacterEncoding("utf-8");

        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for(String value:strings)
        {
            //根据key获取值
            String[] strings1 = parameterMap.get(value);
            for(String s:strings1) {
                System.out.println("key=" + value + "  value=" + s);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doGet(request,response);
    }
在这里插入图片描述
在这里插入图片描述

请求转发

一种在服务器内部资源跳转的方式

在这里插入图片描述
在这里插入图片描述

步骤

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

代码语言:javascript
复制
@WebServlet("/demo")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        System.out.println("转发到dem0....");
        //转发到reqServlet3下面的资源
/*        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/reqServlet3");
requestDispatcher.forward(request,response);*/
        //一般多为链式编程
        request.getRequestDispatcher("/reqServlet3").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doGet(request,response);
    }
}
代码语言:javascript
复制
@WebServlet("/reqServlet3")
public class reqServlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("转发到reqServlet3....");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
在这里插入图片描述
在这里插入图片描述

共享数据(域对象)

域对象: 一个有作用范围的对象,可以在范围内共享数据 request 域: 代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

在这里插入图片描述
在这里插入图片描述

一般只有转发的情况下,才可以用request域共享数据

代码演示:

代码语言:javascript
复制
@WebServlet("/demo")
public class reqServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        System.out.println("转发到dem0....");
        //存储数据到request域中
        request.setAttribute("name","大忽悠");

        request.getRequestDispatcher("/reqServlet3").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doGet(request,response);
    }
}
代码语言:javascript
复制
@WebServlet("/reqServlet3")
public class reqServlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object name = request.getAttribute("name");
        System.out.println((String)name);
        System.out.println("转发到reqServlet3....");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
在这里插入图片描述
在这里插入图片描述

获取ServletContext对象

代码语言:javascript
复制
 ServletContext servletContext = request.getServletContext();

用户登录案例

案例需求

在这里插入图片描述
在这里插入图片描述

案例分析

在这里插入图片描述
在这里插入图片描述

环境准备

  1. 创建项目,导入html页面,配置文件,导入jar包
  2. 创建数据库环境
代码语言:javascript
复制
USE test1;
CREATE TABLE USER(
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(20) UNIQUE NOT NULL,
  PASSWORD VARCHAR(32) NOT NULL
);

3.创建一个user类

代码语言:javascript
复制
package domain;

public class user {
    private int id;
    private  String username;
    private  String password;

    public user(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public user() {
    }

    public int getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

4.创建操作数据库中user表的类—UserDao

代码语言:javascript
复制
package Dao;

import Utils.JDBCUtils;
import domain.user;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class userDao {
    //声明JDBCTemplate对象共用
    private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
    //登录方法
    public user login(user loginUser)
    {
        try
        {
            //编写sql语句
            String sql="select * from user where username= ? and password= ?";
            //调用query方法---返回一个查到的user对象
            user user = template.queryForObject(sql, new BeanPropertyRowMapper<user>(user.class), loginUser.getUsername(), loginUser.getPassword());
            //loginUser: 只包含用户名和密码
            //返回的user: 包括用户全部数据
            return user;
        }
        catch (DataAccessException e)
        {
            e.printStackTrace();
            //没有查询到,返回null
            return null;
        }
    }

}

一个例子教你看源码!深入浅出教你理解Template中的query和queryForObject的区别!

5.工具类

代码语言:javascript
复制
package Utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {
    //定义成员变量---连接池对象
    private static DataSource ds;
    static {
        try {
            //加载配置文件
            Properties pro=new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            //初始化连接池对象
            ds= DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    //获取连接池对象
      public static  DataSource getDataSource()
      {
          return ds;
      }
    //获取连接Connection对象
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

}
  1. loginServlet类完成登录的具体逻辑
代码语言:javascript
复制
在这里插入代码片

7.login.html

login.html中的form表单的action路径写法

虚拟目录+ Servlet的资源路径

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<form action="/demo5/LoginServlet" method="post">
    用户名: <input type="text" name="username" placeholder="请输入用户名"><br>
    密码: <input type="password" placeholder="请输入密码" name="password"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>

8.配置文件

代码语言:javascript
复制
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test1
username=root
password=root
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000

最新版的IDEA需要把配置文件放置到如下两个地方:

在这里插入图片描述
在这里插入图片描述

否则报如下错误:

在这里插入图片描述
在这里插入图片描述

9.loginServlet–负责登录的相关逻辑

代码语言:javascript
复制
import Dao.userDao;
import domain.user;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置编码
        request.setCharacterEncoding("utf-8");
        //2.获取请求参数
        String usermame= request.getParameter("username");
        String password = request.getParameter("password");
        //3.封装user对象
        user loginUser=new user(usermame,password);
        //4.调用userDao的login方法
        userDao dao=new userDao();
        user user=dao.login(loginUser);
        //5.判断user
        if(user==null)
            //登录失败
       request.getRequestDispatcher("/FailServlet").forward(request,response);
        else
        {
            //登录成功
            //存储数据
            request.setAttribute("user",user);//将查到的user对象存入
            //转发
            request.getRequestDispatcher("/SuccessServlet").forward(request,response);
        }


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

10.FailServlet—处理登录失败的逻辑

代码语言:javascript
复制
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/FailServlet")
public class FailServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//给页面写一句话
        //设置页面的编码
        response.setContentType("text/html;charset=utf-8");
        System.out.println("登录失败");
        //输出
        response.getWriter().write("登录失败,用户名或者密码错误");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     doGet(request,response);
    }
}

11.SuccessServlet—处理登录成功的逻辑

代码语言:javascript
复制
import domain.user;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet("/SuccessServlet")
public class SuccessServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //获取request域中共享的user对象
       user user= (user)request.getAttribute("user");
       //给页面写一句话

        //设置编码
        response.setContentType("text/html;charset=utf-8");
        System.out.println("登录成功");
        //输出
        response.getWriter().write("欢迎"+user.getUsername()+"用户");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
    }
}

效果演示:

数据库目前只有一位用户登录成功:

在这里插入图片描述
在这里插入图片描述

登录失败的演示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

登录成功的演示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BeanUtils工具类,简化数据封装

用于封装JavaBean的

JavaBean: 标准的Java类

  1. 类必须被public修饰
  2. 必须提供空参的构造器
  3. 成员变量必须使用private修饰
  4. 必须提供公共的setter和getter方法
  5. 一般像这种JavaBean的类都会放在domain等的包下面

功能:封装数据

概念

  1. 成员变量
  2. 属性: setter和getter截取后的产物,例如: getUsername()—>Username(下一步变小写)–>username,这里的username一般就是成员变量的名字 这里是通过通过传入的字符串和方法名截取后的产物进行比对,找到正确的方法,来设置属性值或者得到属性值

方法

  1. setProperty()—>给属性赋值
  2. getProperty()---->得到属性的值
  3. populate(Object obj,Map map):将map集合的键值对信息封装到对应的JavaBean对象中,把键作为属性的名称,值作为JavaBean对应属性的值

BeanUtils工具类使用前要导入jar包

setProperty()和getProperty()方法演示:

代码语言:javascript
复制
     user loginUser=new user();
        //设置loginUser的属性
        BeanUtils.setProperty(loginUser,"username","大忽悠");
        System.out.println(loginUser);
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
    user loginUser=new user("大忽悠","123456");
        String name= BeanUtils.getProperty(loginUser,"username");
        System.out.println(name);
在这里插入图片描述
在这里插入图片描述

populate方法演示:

代码语言:javascript
复制
/*

        //2.获取请求参数
        String usermame= request.getParameter("username");
        String password = request.getParameter("password");
        //3.封装user对象
        user loginUser=new user(usermame,password);
*/

        //获取所有请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        //创建user对象
        user loginUser=new user();
        //使用BeanUtils进行封装
        try {
            BeanUtils.populate(loginUser,parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

HTTP响应消息

服务器端发送给客户端的数据

数据格式:

1. 响应行

在这里插入图片描述
在这里插入图片描述

2. 响应头

在这里插入图片描述
在这里插入图片描述

3. 响应空行

4. 响应体: 传输的数据


Reponse对象

设置响应消息

1.设置响应行

  1. 格式: http/1.1 200 ok
  2. 设置状态码: setStatus(int sc)

2.设置响应头

代码语言:javascript
复制
setHeader(String name,String value);

3.设置响应体

使用步骤:

  1. 获取输出流
1.1字符输出流1.2字节输出流
1.1字符输出流1.2字节输出流
  1. 使用输出流,将数据输出到客户端浏览器

案例之完成重定向

重定向: 资源跳转的方式

在这里插入图片描述
在这里插入图片描述

代码演示:

代码语言:javascript
复制
        //访问Demo1资源,自动跳转到Demo2资源
        //1.设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/Demo2Servlet");

简单的重定向写法:

代码语言:javascript
复制
 response.sendRedirect("/Demo2Servlet");

重定向和转发的区别和各自特点

在这里插入图片描述
在这里插入图片描述

路径写法

路径分类

在这里插入图片描述
在这里插入图片描述

不写默认代表./ ,即当前目录下

在这里插入图片描述
在这里插入图片描述

动态获取虚拟目录

代码语言:javascript
复制
        String contextPath = request.getContextPath();//虚拟目录
        response.sendRedirect(contextPath+"/Demo2Servlet");

服务器输出字符数据到浏览器

  1. 获取字符输出流
  2. 输出数据

代码演示:

代码语言:javascript
复制
        //获取字符输出流
        PrintWriter writer = response.getWriter();
        //输出数据
        writer.write("<font color=red size=5>Hello world</font>");
在这里插入图片描述
在这里插入图片描述

中文乱码问题

在这里插入图片描述
在这里插入图片描述

解决方法:

代码语言:javascript
复制
        //获取流对象之前,设置流的默认编码: ISO-8859-1 设置为GBK
        response.setCharacterEncoding("GBK");
        //获取字符输出流
        PrintWriter writer = response.getWriter();
        //输出数据
        writer.write("<font color=red size=5>大忽悠</font>");
在这里插入图片描述
在这里插入图片描述

如果在不知道浏览器编码格式的情况下,解决方法如下:

代码语言:javascript
复制
      //获取流对象之前,设置流的默认编码: ISO-8859-1 设置为GBK
        response.setCharacterEncoding("utf-8");
        //告诉浏览器,服务器发送的消息体数据编码,建议浏览器使用该编码编码
        response.setHeader("content-type","text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter writer = response.getWriter();
        //输出数据----这里可以使用html标签,浏览器可以解析
        writer.write("<font color=red size=5>大忽悠</font>");

对上面一种方法的简化写法:

代码语言:javascript
复制
          response.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter writer = response.getWriter();
        //输出数据
        writer.write("<font color=red size=5>大忽悠来了</font>");
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

服务器输出字节数据到浏览器

  1. 获取字节输出流
  2. 输出数据

代码演示:

代码语言:javascript
复制
        response.setContentType("text/html;charset=utf-8");
        //获取字节输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //输出数据
        outputStream.write("大忽悠".getBytes(StandardCharsets.UTF_8));//如果这里不设置字符集,默认使用GBK

一般使用字节输出流来输出图片和视频,而非文本信息


字节输出流案例----验证码

验证码本质是个图片,目的是为了来防止恶意表单注册

完整代码演示:

Demo1Servlet:

代码语言:javascript
复制
package com.example.DEMO7;

import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Random;

@WebServlet("/Demo1Servlet")
public class Demo1Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width=150;
        int height=50;
        //1.在内存中创建一个图片----创建一个不带透明色的对象
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //2.填充背景色
        Graphics g=image.getGraphics();//画笔对象
        g.setColor(Color.PINK);
         g.fillRect(0,0,width,height);
        //3.画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width-1,height-1);

        //4.随机生成验证码
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random ran=new Random();
        for(int i=1;i<=4;i++)
        {
          //生成随机角标
            int index=ran.nextInt(str.length());
            //获取字符
            char ch=str.charAt(index);
            //写验证码
            g.drawString(ch+" ",width/5*i,height/2);
        }
        //7.画干扰线
        //随机生成坐标点
        for(int i=0;i<4;i++)
        {
            int x1=ran.nextInt(width);
            int x2=ran.nextInt(width);
            int y1=ran.nextInt(height);
            int y2=ran.nextInt(height);
            g.setColor(Color.RED);
            g.drawLine(x1,y1,x2,y2);
        }
        //8.将图片输出到页面上----第二个参数是后缀名,第三个参数是一个输出流
        ImageIO.write(image,"jpg",response.getOutputStream());
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

register.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>战地六中国区官网</title>
    <script>
        /*
        * 分析:
        * 点击超链接或者图片,需要换一张验证码图片
        * 1.给超链接和图片绑定单击事件
        * 2.重新设置图片的src属性值
        * */
        //当页面加载完成,触发下面的事件
        window.onload=function (){
            //1.获取图片对象
            var img=document.getElementById("checkCode");
            //2.绑定单击事件
            img.onclick=function ()
            {
                //浏览器会有缓存,因此需要加一个时间戳,保证每次的资源路径都不同
                var date=new Date().getTime();
                img.src="/Demo7/Demo1Servlet?"+date;
            }
        }
    </script>
</head>
<body>
<form  action="/Deom7/Demo1Servlet" method="get">
    游戏激活码:<input type="text" placeholder="请输入激活码"><br>
    验证码:<input type="text" placeholder="输入图片验证码">&nbsp;&nbsp;&nbsp;
    <img id="checkCode" src="/Demo7/Demo1Servlet"/>
    <a id="change" href="http://localhost/Demo7/register.html">看不清换一张?</a>
</form>
</body>
</html>
在这里插入图片描述
在这里插入图片描述

ServletContext对象

概念: 代表整个web应用,可以和程序的容器来通信

获取

在这里插入图片描述
在这里插入图片描述

代码演示:

代码语言:javascript
复制
           //1.通过request对象获取
        ServletContext servletContext = request.getServletContext();
        //2.通过HttpServlet获取
        ServletContext servletContext1 = this.getServletContext();
        System.out.println(servletContext1);
        System.out.println(servletContext);
        System.out.println(servletContext1==servletContext);//true
在这里插入图片描述
在这里插入图片描述

功能

1.获取MIME类型

在这里插入图片描述
在这里插入图片描述

代码演示:

代码语言:javascript
复制
     //通过HttpServlet获取
        ServletContext servletContext = getServletContext();
        //定义文件名称
        String filename="a.jpg";
        //获取MIME类型
        String mimeType = servletContext.getMimeType(filename);
        System.out.println(mimeType);
在这里插入图片描述
在这里插入图片描述

2.域对象,共享数据

在这里插入图片描述
在这里插入图片描述

ServletContext对象的生命周期从服务器被创建时开始,到服务器被关闭时结束,并且作用范围很广,为所有用户,因此要谨慎使用

3.获取文件服务器路径

在这里插入图片描述
在这里插入图片描述

服务器中不同目录下的文件获取时填写路径不同,需要注意

代码语言:javascript
复制
            //获取ServletContext对象----HTTP方式
        ServletContext servletContext = getServletContext();

        //获取文件的服务器路径
        //web目录下的资源访问
        String realPath = servletContext.getRealPath("/b.txt");
        System.out.println(realPath);

        //web-inf目录下的资源访问
        String realPath1 = servletContext.getRealPath("/WEB-INF/c.txt");
        System.out.println(realPath1);

        //java目录下的资源访问
        String realPath2 = servletContext.getRealPath("/WEB-INF/classes/a.txt");
        System.out.println(realPath2);
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件下载案例

文件下载需求:

  1. 页面显示超链接
  2. 点击超链接后弹出下载提示框
  3. 完成图片文件下载

分析:

在这里插入图片描述
在这里插入图片描述

步骤:

在这里插入图片描述
在这里插入图片描述

上面说过的响应头相关知识回顾:

在这里插入图片描述
在这里插入图片描述

代码实现:

代码语言:javascript
复制
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求参数,即文件名称
        String filename=request.getParameter("filename");
        //使用字节输入流加载文件进内存
        //第一步: 找到文件服务器路径
        ServletContext servletContext = getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //第二步: 用字节流关联
        FileInputStream fis=new FileInputStream(realPath);

        //设置response的响应头
        //第一步: 设置响应头的类型: content-type
        String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);
        //第二步: 设置响应头打开的方式: content-disposition
        response.setHeader("content-disposition","attachment;filename="+filename);//filename=....弹出提示框的名字

        //将输入流数据写到输出流中
        ServletOutputStream outputStream = response.getOutputStream();
           byte[] buff=new byte[1024*8];
           int len=0;
           while((len=fis.read(buff))!=-1)
           {
               outputStream.write(buff,0,len);
           }
           //关闭输入流
        fis.close();
    }

downLoad.html:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<a href="/demo9/img/cat.png">可爱小猫</a>
<a href="/demo9/img/lion.png">猛狮</a>
<hr>
<font color="#ff69b4" size="5">下面链接,点击下载图片</font><br>
<a href="/demo9/downLoadServlet?filename=cat.png">小猫图片下载</a>
<a href="/demo9/downLoadServlet?filename=lion.png">狮子图片下载</a>
</body>
</html>
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

中文文件名问题

在这里插入图片描述
在这里插入图片描述

解决:

在这里插入图片描述
在这里插入图片描述

如果jdk版本打印1.8,那么需要手动导入BASE64Encoder的jar包,方可使用其工具类

工具类代码:

代码语言:javascript
复制
package com.example.Demo9;
import Decoder.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class downLoadUtils {

    public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

之前出问题的servlet主类:

代码语言:javascript
复制
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求参数,即文件名称
        String filename=request.getParameter("filename");
        //使用字节输入流加载文件进内存
        //第一步: 找到文件服务器路径
        ServletContext servletContext = getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //第二步: 用字节流关联
        FileInputStream fis=new FileInputStream(realPath);

        //设置response的响应头
        //第一步: 设置响应头的类型: content-type
        String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);
        //第二步: 设置响应头打开的方式: content-disposition
        
        ///
        //解决中文文件名问题
        //1.获取user-agent请求头
        String agent=request.getHeader("user-agent");
        //2.使用工具类方法编码文件名即可
        filename = downLoadUtils.getFileName(agent, filename);
        ///
        
        response.setHeader("content-disposition","attachment;filename="+filename);//filename=....弹出提示框的名字

        //将输入流数据写到输出流中
        ServletOutputStream outputStream = response.getOutputStream();
           byte[] buff=new byte[1024*8];
           int len=0;
           while((len=fis.read(buff))!=-1)
           {
               outputStream.write(buff,0,len);
           }
           //关闭输入流
        fis.close();
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Tomact和servlet快速入门教程
  • tomcat的入门必备知识
    • 1.下载:
      • 2.安装: 解压压缩包即可
        • 3.卸载: 删除目录即可
          • 4.启动:
            • 5.关闭:
              • 6.部署:
                • 静态项目和动态项目
            • 将tomcat集成到IDEA中,并且创建JavaEE项目,部署项目
            • Servlet
              • web动态工程目录介绍
                • 热部署
                  • 快速入门
                    • URL地址定位实现原理
                      • 生命周期方法
                      • 注解配置
                        • 步骤:
                        • IDEA与tomcat的相关配置
                        • Servlet的体系结构
                        • Servlet的urlpattern配置
                        • Http
                          • Http请求数据格式
                          • Request对象
                            • Request对象的继承体系结构
                              • Request的功能
                                • 获取请求行数据
                                • 获取请求头数据
                                • 获取请求体数据
                                • 获取请求参数的通用方式
                              • 请求转发
                                • 步骤
                              • 共享数据(域对象)
                                • 获取ServletContext对象
                                  • 用户登录案例
                                    • 案例需求
                                    • 案例分析
                                    • 环境准备
                                  • BeanUtils工具类,简化数据封装
                                    • JavaBean: 标准的Java类
                                    • 概念
                                    • 方法
                                • HTTP响应消息
                                  • 1. 响应行
                                    • 2. 响应头
                                      • 3. 响应空行
                                        • 4. 响应体: 传输的数据
                                        • Reponse对象
                                          • 1.设置响应行
                                            • 2.设置响应头
                                              • 3.设置响应体
                                              • 案例之完成重定向
                                                • 简单的重定向写法:
                                                • 重定向和转发的区别和各自特点
                                                • 路径写法
                                                  • 路径分类
                                                    • 动态获取虚拟目录
                                                      • 服务器输出字符数据到浏览器
                                                        • 中文乱码问题
                                                      • 服务器输出字节数据到浏览器
                                                        • 字节输出流案例----验证码
                                                        • ServletContext对象
                                                          • 获取
                                                            • 功能
                                                              • 1.获取MIME类型
                                                                • 2.域对象,共享数据
                                                                  • 3.获取文件服务器路径
                                                                    • 文件下载案例
                                                                      • 中文文件名问题
                                                                  相关产品与服务
                                                                  验证码
                                                                  腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
                                                                  领券
                                                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档