2021年9月10日

今天的内容

1.servlet注解(以后开发用)和配置文件(以后不用)的写法

2.Servlet的生命周期【面试会问】

3.获取前端请求的参数

4.通过前端发送数据到servlet,然后存入数据库

5.中文乱码的解决方案

6.重定向和转发

1.Servlet注解和配置文件的写法

咱们刚才写的Servlet是注解的写法 @WebServlet("/test")

1.1配置文件的写法【如果Servlet版本低的话】

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_3_1.xsd"
        version="3.1">
   <servlet>
<!--       对servlet起一个名字,这个名字要和一个标签servlet-mapping对应-->
       <servlet-name>sb</servlet-name>
<!--       servlet-class是咱们servle所对应的类-->
       <servlet-class>com.qfedu.b_servlet.WebXMLServlet</servlet-class>
<!--       当tomcat服务器已启动就会加载这个类-->
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>sb</servlet-name>
<!--     url-pattern 找到这个资源的入门,类似于咱们写的@WebServlet("/webxml") -->
<!--       可以写多个url-pattern 相当于给资源起了很多的名字
       但是请求只有一个WebXMLServlet
-->
       <url-pattern>/webxml</url-pattern>
       <url-pattern>/web.do</url-pattern>
       <url-pattern>/sb.action</url-pattern>
   </servlet-mapping>
</web-app>
package com.qfedu.b_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 WebXMLServlet extends HttpServlet {
   @Override
   public void init() throws ServletException {
       System.out.println("初始化");
  }

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

   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.setContentType("text/html;charset=utf-8");
       resp.getWriter().append("这个是配置文件的写法");
  }
}

1.2注解的写法【以后用这个】

这种写只能是Servlet版本是3.0以上的版本才可以使用注解,

现在咱们都是3.0以上的了。所以以后用注解的写法。从这地方可以说明一个问题

去xml的写法,xml太麻烦了。咱们ssm框架 大部分都是xml,后来出来一个springboot

把xml省去了,加了好多的注解。

package com.qfedu.b_servlet;

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;


/*
* @WebServlet的几个属性
* name 是servlet的名字无所谓
* urlPatterns 是url匹配规则 可以写多个
* loadOnStartup = 1 当tomacat服务器启动的时候 会加载这个类1
*           -1 当去请求的时候才去加载这个类
* value 就是写咱们url 只能写一个
* */
@WebServlet(name = "AnnotionServlet",value="/anno" ,
           loadOnStartup = 1)
public class AnnotionServlet extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.setContentType("text/html;charset=utf-8");
       resp.getWriter().append("这个是注解的写法");
  }

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

2.Servlet的生命周期

Servlet在执行的时候,经历过这些过程:

1.construct

2.init

3.service

4.destory

阶段1:

Servlet这个类在Tomcat中进行了实例化,提供给Tomcat使用

阶段2:

Servlet的初始化

阶段3:

Servlet对外提供服务,相当于doGet和doPost方法

阶段4:

servlet进行销毁,可以手动销毁,调用destroy方法,咱们一般不用调用,tomcat只要关闭就会销毁Servlet

package com.qfedu.c_servlet;

import javax.servlet.ServletConfig;
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;

@WebServlet("/life.do")//注解
public class LifeServlet extends HttpServlet {
   //为了验证这个LifeServlet被实例化了没
   //因为咱们的生命周期第一步就是实例化
   //如果真的被实例化了,那么这个无参构造构造方法肯定要执行
   public LifeServlet() {
       System.out.println("我是LIfeServlet的无参数构造方法");
  }
   //验证第二步:初始Servlet

   @Override
   public void init(ServletConfig config) throws ServletException {
       System.out.println("我是LifeServlet的初始化");
  }

   //验证生命周期的第三步:是否执行了service方法 核心方法
   @Override
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       System.out.println("我是LifeServlet的Service方法");
  }
   //验证第四部:销毁Servlte

   @Override
   public void destroy() {
       System.out.println("销毁!!!");
  }
}

3.获取前端请求的参数

我说过,想要学好Servlet必须紧紧围绕着两个东西

请求和响应这两个概念。

问大家一个问题?咱们现在写的代码只是进行请求,然后再响应到客户端。

请求的时候带数据给Servlet了没?没有带数据给Servlet

现在咱们要讲在请求的时候前端带数据到Servlet里面。咱们Servlet要接受前端给我的这个数据

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
<!--提交到一个Servlet中不用带斜线-->
<form action="LoginServlet" method="get">
  姓名:<input type="text" name="user"><br>
  密码:<input type="password" name="pwd"><br>
   <input type="submit" value="提交">
</form>
</body>
</html>
package com.qfedu.d_servlte;

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;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //前端发送数据到我这servlet了,我这个Servlet能不能接一些数据?
       //前端发送求过来,说明和request 对象
       //http:localhost:8080/login.html?user=gouda&pwd=12123
       //这个getParameter方法就是获取请求对象的参数的,通过
       //前端input标签name的属性值获取的
       //解决post请求时候的乱码
       request.setCharacterEncoding("utf-8");
       String user = request.getParameter("user");
       String pwd = request.getParameter("pwd");
       System.out.println(user + ":" + pwd);

  }
}

4.通过前端发送数据到servlet,然后存入数据库

类似于注册功能

1.先写一个html页面,主要发送数据给Servlet

2.写一个RegisterServlet,这个Servlet的目的获取前端传过来的数据

3.咱们得想办法把获取到的数据存到数据库

4.封装的JdbUtil和BaseDao还记得吗?

使用druid还是c3p0连接池呢?

5.赋值黏贴过来

6.我想使用BaseDao这个类方法update 7.需要再写一个类去继承BaseDao,这个类(UserDao)是专门写sql处理数相关的类

8.在Servlet里面实例化UserDao调用UserDao下面的方法即可!!!

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
<!--提交到一个Servlet中不用带斜线-->
<!--如果是get请求,给Servlet的时候中文不会乱码
但是是post请求的时候,中文会乱码
-->
<form action="RegisterServlet" method="post">
  姓名:<input type="text" name="user"><br>
  密码:<input type="password" name="password"><br>
   <input type="submit" value="注册">
</form>
</body>
</html>
package com.qfedu.e_servlet;

import com.qfedu.util.BaseDao;

import java.sql.SQLException;

//会讲MVC的架构思想
//dao的都是写sql处理增删改查的
public class UserDao extends BaseDao {

   public int addUser(Object[] objs) throws SQLException {
       String sql = "insert into user(name, password) values(?,?)";
       return super.update(sql, objs);
  }
}
package com.qfedu.e_servlet;

import com.qfedu.util.BaseDao;

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.sql.SQLException;

@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //获取前端传过来的数据
       request.setCharacterEncoding("utf-8");
       String user = request.getParameter("user");
       String password = request.getParameter("password");
       //现在能拿到了user 和password,把这两个值存到数据库
       //BaseDao baseDao = new BaseDao();
       //准备一个sql语句,还有准备参数,参数是一个吧数组
       //一般Servlet里面不让写sql语句 怎么办?这个确实能实现数据库数据的添加n
       //但是不规范,sql单独放在另外一个类中

//       String sql = "insert into user(name, password) values(?,?)";
//       Object[] objs = {user, password};
//       try {
//           baseDao.update(sql, objs);
//       } catch (SQLException e) {
//           e.printStackTrace();
//       }
       //把sql语句写在了另外一个类中
       UserDao userDao = new UserDao();
       Object[] objs = {user, password};
       try {
           userDao.addUser(objs);
      } catch (SQLException e) {
           e.printStackTrace();
      }


  }
}

5.中文乱码的解决方案

请求时候的中文乱码的问题:
前端发送数据到Servlet 如果是post请求的话,input输入中文数据的时候,Servlet接到的数据是乱码的。
request.setCharacterEncoding("utf-8");
响应时候的中文乱码的问题:
Servlet响应数据到客户端的时候,如果是中文的话,会乱码
response.setContentType("text/html;charset=utf-8");

6.重定向和转发【重要】

web网站上面有一些跳转按钮。比如 登录成功以后跳转到主页面!!!

6.1重定向

用户通过浏览器发送一个请求,Tomcat服务器接收这个请求,会给浏览器发送一个状态码302

并设置一个重定向的路径,浏览器如果接收到,了这个302的状态码以后,就会去自动加载服务器设置的路径。

一个页面跳转到另外一个页面(场景)

登录页面跳转到主页

denglu.html===>TestLoginServlet=>target.html

特征:

1.重定向的过程是浏览器(客户端)的行为

2.实际上浏览器做了几次请求 (当点击登录按钮的时候做了两次请求)(TestLoginServlet,target.html)

3.注意上一次请求的request对象会丢失

4.重定向有一个非常明显的特征,浏览器的url变化了

5.重定向可以重定向到网络的任意资源(比如京东淘宝等网络资源)

response.sendRedirect("target.html");就这一行代码,但是这一行代码必须写在doget或者dopost

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--提交到一个Servlet中不用带斜线-->
<!--如果是get请求,给Servlet的时候中文不会乱码
但是是post请求的时候,中文会乱码
-->
<form action="TestLoginServlet" method="post">
    姓名:<input type="text" name="user"><br>
    密码:<input type="password" name="pwd"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>
package com.qfedu.f_servlet;

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;

@WebServlet("/TestLoginServlet")
public class TestLoginServlet extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       request.setCharacterEncoding("utf-8");//请求时候的中文乱码
       //获取到前端发送过来的年数据
       String user = request.getParameter("user");
       String password = request.getParameter("pwd");
       //登录以后跳转到主页
       //重定向
       //这个TestLoginServlet里面的数据是不能传给target.html
       response.sendRedirect("target.html");
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
我是主页
</body>
</html>

6.2转发

用户发送请求到服务器

服务器接收当前请求

会调用内部方式(转发)处理该请求

最终把响应给客户端

特征:

1.转发是服务器的行为

2.浏览器在中那个过程中只有一次行为

3.转发可以带有数据 request对象中

4.url不会发生任何变化的

5.转发只能在当前项目中进行转发,不能转发外部的资源

request.getRequestDispatcher("TestServlet2").forward(request,response);
就这一行代码进行了转发
url没有变,但是响应的结果却是另外一个Servlet里面的东西
一次请求干了两个活
package com.qfedu.f_servlet;

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;

@WebServlet("/TestServlet1")
public class TestServlet1 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       System.out.println("用户请求TestServlet1");
       //给当前的request对象设置一些数据,request对象带有数据
       //name = 猪肉邢
       request.setAttribute("name", "猪肉邢");
       /*
       可以通过request对象转发到其他资源(另外一个Servlet)里面
       * */
       //转发会将一个Servlet里面数据带到另外一个servlet里面
       request.getRequestDispatcher("TestServlet2").forward(request,response);
  }
}
package com.qfedu.f_servlet;

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;

@WebServlet("/TestServlet1")
public class TestServlet1 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       System.out.println("用户请求TestServlet1");
       //给当前的request对象设置一些数据,request对象带有数据
       //name = 猪肉邢
       request.setAttribute("name", "猪肉邢");
       /*
       可以通过request对象转发到其他资源(另外一个Servlet)里面
       * */
       //转发会将一个Servlet里面数据带到另外一个servlet里面
       request.getRequestDispatcher("TestServlet2").forward(request,response);
  }
}

6.3综合案例

登录页面

点击登录按钮(判断前端传给我的数据在数据库中是否存在)

如果用户名和密码都是正确我才让你登录,转发到主页面

转发到主页

<%--
 Created by IntelliJ IDEA.
 User: wangbo
 Date: 2021/9/10
 Time: 15:51
 To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
   <form action="LoginServlet" method="post">
       <input type="text" name="username">
       <input type="password" name="pwd">
       <input type="submit" value="登录">
   </form>
</body>
</html>
package com.qfedu.a_servlet;

public class User {
    //这个属性名字一定要和数据库表中字段对应好一个单词都不能写错
    private  int id;
    private String name;
    private String password;
    public User() {

    }

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

}
package com.qfedu.a_servlet;

import com.qfedu.utils.BaseDao;

import java.sql.SQLException;
import java.util.List;

public class UserDao extends BaseDao {

    public List<User> selectUser(Object[] objs) throws SQLException {
        String sql = "select * from user where name=?";
        //查出来一条数据以后赋值给这个实体类
        List<User> users = super.query(sql, objs, User.class);
        return users;
    }

}
package com.qfedu.a_servlet;

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.sql.SQLException;
import java.util.List;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //先设置字符集
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //1.获取前端页面的数据
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        //连接数据库和咱们数据表中数据做对比?如果有这条
        //数据并且密码也是正确的我就让你进入到主页面
        //如果密码和用户名没有匹配成功我就让你跳转到失败页面
        //这个sql语句是一个查询的sql语句,得有返回值,得用一个实体类来接一下
        UserDao userDao = new UserDao();
        Object[] objs = {username};
        try {
            //前端给我传过来的username ,和数据库里面name字段去比较
            List<User> users = userDao.selectUser(objs);
            if(users != null) {
                //[user1,user2]
                User user = users.get(0);//List集合的第一个数据
                //判断密码
                //pwd   input输入框中输入的
                //user.getPassword()  数据库取出来赋值给user对象了,然后再从user对象中取出来
                if(pwd.equals(user.getPassword())) {
                    request.setAttribute("username", username);
                    //匹配用户名和密码以后转发
                    request.getRequestDispatcher("index.jsp").forward(request,response);
                }else{
                    //密码错误
                    response.getWriter().append("密码错误");
                }
            }else{
                response.getWriter().append("用户不存在");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}
<%--
  Created by IntelliJ IDEA.
  User: wangbo
  Date: 2021/9/10
  Time: 15:49
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  欢迎<font size="50px" color="red"><%=request.getAttribute("username")%></font>来到红浪漫洗浴中心
  </body>
</html>



posted @ 2021-09-11 16:06  张三疯321  阅读(38)  评论(0)    收藏  举报