【Servlet】规范项目结构|基于Mysql+JDBC+Servlet 制作简易网页|实现登录、添加、删除、显示的功能

✅作者简介:热爱后端语言的大学生,CSDN内容合伙人
✨精品专栏:C++面向对象
🔥系列专栏:javaweb


🔥前言

书接上文,今天我们来规范书写servlet代码,分包分类的规划项目结构。我们知道一个项目靠一个人是很难完成的,那么在团队合作的时候难免会有看不懂队友写的代码的情况出现。因此按照特定的格式来书写代码无疑可以一定程度上减少这种事情发生的概率。


1、需要导入的jar包以及项目结构速览

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

在这里插入图片描述

2、工具类放在util包下,资源文件放在src目录下

工具类最终版JDBCUtils可参考我JDBC专栏里的博文,资源文件就是图中的jdbc.properties,里面存放数据库的驱动路径、访问路径、账号名和密码。

3、具体类写在实体类的包下(entity)

以此次博客要分享的项目为例:

我要做的是一个有登录和增删查询功能的网页,因此可以定义一个Person类,实现Serializable接口(形成习惯),封装姓名、密码等属性并提供对应的构造方法(不要忘了写无参构造)

具体代码如下:

package com.qj.entity;
import java.io.Serializable;
public class Person implements Serializable {
    private Integer id;
    private String name;
    private String pwd;
    private String QQ;
    private String beizhu;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                ", QQ='" + QQ + '\'' +
                ", beizhu='" + beizhu + '\'' +
                '}';
    }
    public Person(Integer id, String name, String pwd, String QQ, String beizhu) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
        this.QQ = QQ;
        this.beizhu = beizhu;
    }

    public Person() {
    }

    public Person(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public String getQQ() {
        return QQ;
    }

    public void setQQ(String QQ) {
        this.QQ = QQ;
    }

    public String getBeizhu() {
        return beizhu;
    }

    public void setBeizhu(String beizhu) {
        this.beizhu = beizhu;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

4、dao层接口与接口的实现类

dao层是与数据库对接的,存放操作数据库的接口方法。而在dao包里面还有一个impl包用来存放接口的实现类,用来操作数据库,例如:增删改查

4.1、PersonDao接口

这里提供了几种方法接口:

  1. 根据查询名字返回person对象
  2. 查询数据库中的所有人并存入list集合中
  3. person信息插入到数据库中
  4. 根据id删除数据库中的person
package com.qj.dao;
import com.qj.entity.Person;
import java.util.List;
public interface PersonDao {
    /**
     *
     * @param name  用户输入的名字
     * @return      返回数据库里的Person对象
     */
    Person selectByName(String name);
    /**
     *
     * @return  返回t_Perosn表中所有人
     */
    List<Person> selectAll();
    /**
     *
     * @param person  插入到表格
     * @return        受影响行数
     */
    int insertPerson(Person person);
    /**
     *
     * @param id      按照id删除好友
     * @return        返回受影响行数
     */
    int deletePerson(Integer id);
}

4.2、PersonDaoImpl接口实现类

这里就是针对PersonDao接口的具体实现代码,如果有看不懂的可以参考我的JDBC专栏的文章

package com.qj.dao.impl;
import com.qj.dao.PersonDao;
import com.qj.entity.Person;
import com.qj.util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class PersonDaoImpl implements PersonDao {
    @Override
    public Person selectByName(String name) {
        Connection conn = null;
        PreparedStatement ps=null;
        ResultSet rs = null;
        Person person = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "select *from t_Person where p_name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, name);
            rs = ps.executeQuery();
            if (rs.next()) {
                String l_name = rs.getString("p_name");
                String l_pwd = rs.getString("p_password");
                person = new Person(l_name, l_pwd);
            }
        } catch (Exception e) {
            System.out.println("未知异常");
            e.printStackTrace();
        }finally {
            JDBCUtils.close(rs, ps, null);
        }
        return person;
    }

    @Override
    public List<Person> selectAll() {
        Connection conn = null;
        PreparedStatement ps=null;
        ResultSet rs = null;
        List<Person> list = new ArrayList<>();
        try {
            conn = JDBCUtils.getConnection();
            String sql = "select *from t_Person";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                Integer id = rs.getInt("p_id");
                String name = rs.getString("p_name");
                String pwd = rs.getString("p_password");
                String QQ = rs.getString("p_QQ");
                String beizhu = rs.getString("p_bz");
                Person p = new Person(id, name, pwd, QQ,beizhu);
                list.add(p);
            }
        } catch (Exception e) {
            System.out.println("未知异常");
            e.printStackTrace();
        }finally {
            JDBCUtils.close(rs, ps, null);
        }
        return list;
    }

    @Override
    public int insertPerson(Person person) {
        Connection conn = null;
        PreparedStatement ps=null;
        int n=0;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "insert into t_Person value(null,?,?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, person.getName());
            ps.setString(2, person.getPwd());
            ps.setString(3, person.getQQ());
            ps.setString(4, person.getBeizhu());
            n = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(null, ps, null);
        }
        return n;
    }

    @Override
    public int deletePerson(Integer id) {
        Connection conn = null;
        PreparedStatement ps=null;
        int n=0;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "delete from t_Person where p_id=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, id);
            n = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(null, ps, null);
        }
        return n;
    }
}

5、service层接口与接口实现类

service层存放调用dao层的接口,和其名字一样,是为了方便用户操作数据库而设立的。而service层下也有impl层,存放service接口的实现类。

5.1、PersonService接口

  • login为登录、showAllPerson为显示数据库信息
  • addremove分别对应增加和删除功能
package com.qj.service;
import com.qj.entity.Person;
import java.util.List;
public interface PersonService {
    /**
     *
     * @param name  用户名
     * @param pwd   密码
     * @return      登录结果
     */
    boolean login(String name, String pwd);
    /**
     *
     * @return  返回查询结果集
     */
    List<Person> showAllPerson();
    /**
     *
     * @param person  通过网页输入好友信息
     * @return        返回受影响行数
     */
    int add(Person person);
    /**
     *
     * @param id    通过点击网页按钮删除
     * @return        受影响行数
     */
    int remove(Integer id);
}

5.2、PersonServiceImpl接口实现类

package com.qj.service.impl;
import com.qj.dao.PersonDao;
import com.qj.dao.impl.PersonDaoImpl;
import com.qj.entity.Person;
import com.qj.service.PersonService;
import java.util.List;
public class PersonServiceImpl implements PersonService {
    PersonDao pd = new PersonDaoImpl();
    @Override
    public boolean login(String name, String pwd) {
        Boolean boo=false;
        Person p = pd.selectByName(name);
        if (p != null) {
            if (p.getPwd().equals(pwd)) {
                boo = true;
            }
        }
        return boo;
    }
    @Override
    public List<Person> showAllPerson() {
        return pd.selectAll();
    }
    @Override
    public int add(Person person) {
        return pd.insertPerson(person);
    }
    @Override
    public int remove(Integer id) {
        return pd.deletePerson(id);
    }
}

6、servlet包分为controller包和view包

由于servlet中的service方法具有两种参数:用户请求参数req和响应参数resp,因此把其分到两个包下更合理。

  1. 有关需求参数req放在controller包中,负责接收用户数据以及向view中传送数据
    • 存入要传输的数据使用:req.setAttribute()
      • 该方法含有两个参数,第一个是String类型,第二个是Object类型
      • 用法相当于键值对:第一个参数存入键,第二个参数存入值
    • 自动跳转路径使用:req.getRequestDispatcher().forward(req,resp)
      • 该方法形参传入相对路径即可,以/开头
      • 千万注意要加上后面的.forword(req,resp) (我老是忘加,导致数据无法传送)
  2. 有关响应参数resp放在view包中,接收controller包传送的数据并将效果显示到浏览器页面
    • 获取req传送的数据使用:req.getAttribute()
      • 该方法含有一个参数,需要输入传进来的
      • 由于值的类型是Object,通常需要进行类型强转
        例如:boolean boo = (boolean) req.getAttribute("boo")
    • 通过resp参数也可以进行网页的跳转,但是一般认为不能存入数据(存的非常有限)
      • resp.sendRedirect()
      • 括号内填入绝对路径,也要以/开头

6.1、controller包下的四个servlet类

这里包引入情况基本一致,因此博文里只粘贴一次,此外要注意对外访问路径均采用注解的方式

6.1.1、LoninController类

package com.qj.controller;
import com.qj.service.PersonService;
import com.qj.service.impl.PersonServiceImpl;
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("/login")
public class LoginController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String name = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        PersonService ps = new PersonServiceImpl();
        Boolean boo = ps.login(name, pwd);
        req.setAttribute("boo", boo);
        req.getRequestDispatcher("/loginView").forward(req, resp);
    }
}

6.1.2、AddPersonController类

@WebServlet("/addPerson")
public class AddPersonController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String name = req.getParameter("name");
        String QQ = req.getParameter("QQ");
        String bz = req.getParameter("bz");
        Person p = new Person(null, name, null, QQ, bz);
        PersonService ps = new PersonServiceImpl();
        int n = ps.add(p);
        req.setAttribute("n", n);
        req.getRequestDispatcher("/addPersonView").forward(req,resp);
    }
}

6.1.3、ShowPersonController类

@WebServlet("/showPerson")
public class ShowPersonController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PersonService ps = new PersonServiceImpl();
        List<Person> list = ps.showAllPerson();
        req.setAttribute("list", list);
        req.getRequestDispatcher("/showPersonView").forward(req,resp);
    }
}

6.1.4、DeletePersonController类

@WebServlet("/delete")
public class DeletePersonController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = new Integer(req.getParameter("id"));
        PersonService ps = new PersonServiceImpl();
        int n = ps.remove(id);
        req.setAttribute("n", n);
        req.getRequestDispatcher("/deletePersonView").forward(req, resp);
    }
}

6.2、view包下的四个servlet类

6.2.1、LoginView类

package com.qj.view;

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.io.PrintWriter;

@WebServlet("/loginView")
public class LoginView extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter pw = resp.getWriter();
        boolean boo = (boolean) req.getAttribute("boo");
        if (boo) {
            resp.sendRedirect("/MyfirstServlet/showPerson");
        }else{
            resp.sendRedirect("/MyfirstServlet/login.html");
        }
    }
}

6.2.2、AddPersonView类

@WebServlet("/addPersonView")
public class AddPersonVIew extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int n = (int) req.getAttribute("n");
        if (n > 0) {
            resp.sendRedirect("/MyfirstServlet/showPerson");
        } else {
            resp.sendRedirect("/MyfirstServlet/add.html");
        }
    }
}

6.2.3、ShowPersonView类

@WebServlet("/showPersonView")
public class ShowPersonView extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        List<Person> list = (List<Person>) req.getAttribute("list");
        PrintWriter pw = resp.getWriter();
        pw.println("<html><head><meta charset='utf-8'> </head><body>");
        pw.println("ID 姓名 QQ&emsp;&emsp;&emsp;&emsp;备注"+"<br>");
        for (Person p : list) {
            pw.print(+p.getId()+"&nbsp;");
            pw.print(p.getName()+"&nbsp;");
            pw.print(p.getQQ()+"&nbsp;");
            pw.print(p.getBeizhu()+"&emsp;");
            pw.print("<a href='/MyfirstServlet/delete?id="+p.getId()+"'>点击删除</a>");
            pw.println("<br>");
        }
        pw.println("<a href='/MyfirstServlet/add.html'>添加好友</a>");
        pw.println("</body></html>");
        pw.flush();
    }
}

6.2.4、DeletePersonView类

@WebServlet("/deletePersonView")
public class DeletePersonView extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        int n = (int) req.getAttribute("n");
        PrintWriter pw = resp.getWriter();
        if (n > 0) {
            resp.sendRedirect("/MyfirstServlet/showPerson");
        } else {
            pw.println("删除失败!");
        }
        pw.flush();
    }
}

7、test包用来存放测试类(@Test)

在实战开发中为了提高调试效率会经常使用注解开发,给dao层或者service层阿进行方法测试

这里我就测试了一下添加和显示的功能:

package com.qj.test;
import com.qj.entity.Person;
import com.qj.service.PersonService;
import com.qj.service.impl.PersonServiceImpl;
import org.junit.Test;
import java.util.List;
public class PersonTest {
    PersonService ps = new PersonServiceImpl();
    @Test
    public void showPserson(){
        List<Person> list = ps.showAllPerson();
        for (Person person : list) {
            System.out.println(person.toString());
        }
    }
    @Test
    public void addPerson(){
        Person person = new Person(null, "张三", null, "3110124130", "淳朴张");
        int n = ps.add(person);
        System.out.println(n);
    }
}

测试效果:

在这里插入图片描述

这里第一行的1意为成功插入一条数据,后面两条person属性就是数据库中的查询结果

8、前端整合

8.1、登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加好友</title>
</head>
<body>
输入好友信息:<br>
    <form action="/MyfirstServlet/addPerson" method="get">
      名字:<input type="text" name="name"><br>
      Q Q:<input type="text" name="QQ"><br>
      备注:<input type="text" name="bz"><br>
      <input type="submit" value="添加">
    </form>
</body>
</html>

8.2、添加好友页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录界面</title>
</head>
<body>
    <form action="/MyfirstServlet/login" method="get">
        登录账号:<input type="text" name="username"><br>
        登录密码:<input type="password" name="pwd"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

9、数据库设计和项目效果展示

  1. 表格结构
    在这里插入图片描述

  2. 登录界面
    在这里插入图片描述

  3. 显示页面
    在这里插入图片描述

  4. 添加好友界面
    在这里插入图片描述

  5. 添加成功跳转至显示页面
    在这里插入图片描述

  6. 删除好友并跳转至显示页面
    在这里插入图片描述


以我目前所学就只能做到这儿了,项目虽然很简陋,但主要想分享给大家项目结构的构建。码文不易,希望能得到你们的支持,以此来激励我不断更文!

  • 54
    点赞
  • 43
    收藏
  • 打赏
    打赏
  • 73
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:代码科技 设计师:Amelia_0503 返回首页
评论 73

打赏作者

微凉秋意

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值