【Servlet】规范项目结构|基于Mysql+JDBC+Servlet 制作简易网页|实现登录、添加、删除、显示的功能
原创
©著作权归作者所有:来自51CTO博客作者wx631451f00e5b0的原创作品,请联系作者获取转载授权,否则将追究法律责任
文章目录
- 1、需要导入的jar包以及项目结构速览
- 2、工具类放在util包下,资源文件放在src目录下
- 3、具体类写在实体类的包下(entity)
- 4、dao层接口与接口的实现类
- 4.1、PersonDao接口
- 4.2、PersonDaoImpl接口实现类
- 5.1、PersonService接口
- 5.2、PersonServiceImpl接口实现类
- 6、servlet包分为controller包和view包
- 6.1、controller包下的四个servlet类
- 6.1.1、LoninController类
- 6.1.2、AddPersonController类
- 6.1.3、ShowPersonController类
- 6.1.4、DeletePersonController类
- 6.2、view包下的四个servlet类
- 6.2.1、LoginView类
- 6.2.2、AddPersonView类
- 6.2.3、ShowPersonView类
- 6.2.4、DeletePersonView类
- 7、test包用来存放测试类(@Test)
- 8、前端整合
- 8.1、登录页面
- 8.2、添加好友页面
🔥前言
书接上文,今天我们来规范书写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接口
这里提供了几种方法接口:
- 根据查询名字返回
person
对象 - 查询数据库中的所有人并存入
list
集合中 - 将
person
信息插入到数据库中 - 根据
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
为显示数据库信息 -
add
与remove
分别对应增加和删除功能
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
,因此把其分到两个包下更合理。
- 有关需求参数
req
放在controller
包中,负责接收用户数据以及向view中传送数据
- 存入要传输的数据使用:
req.setAttribute()
- 该方法含有两个参数,第一个是
String
类型,第二个是Object
类型 - 用法相当于键值对:第一个参数存入键,第二个参数存入值
- 自动跳转路径使用:
req.getRequestDispatcher().forward(req,resp)
- 该方法形参传入相对路径即可,以
/
开头 - 千万注意要加上后面的
.forword(req,resp)
(我老是忘加,导致数据无法传送)
- 有关响应参数
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 备注"+"<br>");
for (Person p : list) {
pw.print(+p.getId()+" ");
pw.print(p.getName()+" ");
pw.print(p.getQQ()+" ");
pw.print(p.getBeizhu()+" ");
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、数据库设计和项目效果展示
- 表格结构
- 登录界面
- 显示页面
- 添加好友界面
- 添加成功跳转至显示页面
- 删除好友并跳转至显示页面
以我目前所学就只能做到这儿了,项目虽然很简陋,但主要想分享给大家项目结构的构建。码文不易,希望能得到你们的支持,以此来激励我不断更文!