Servlet 架构思路(MVC)
Posted 程序猿追
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet 架构思路(MVC)相关的知识,希望对你有一定的参考价值。
这几天在做一个前后端分离的一个项目,采用的是 MVC 模式,对于 MVC 网上的教程杂乱无章,也没有写的较详细的,所以写了此文,本文作为一个分享文,分享本人在学习中遇到的问题以及一些自个认为好用的小技巧。
目录
目录下的结构
config
jdbc.properties
src
com.xxx
user(一般与项目名挂钩)
control
UserServlet.java
dao
impl
UserDao.java
IUserDao.java
model
User.java
service
impl
UserService.java
IUserService.java
util
JdbcUtil.java
web
web-inf
web.xml
lib
xxx.jar
xxx.jsp
配置文件
jdbc.properties : 开发中获得连接的4个参数(驱动、URL、用户名、密码)通常都存在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可。
oracle 版
username=itxzw
password=123456
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
mysql 版
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false
或
url=jdbc:mysql://localhost/db1?useSSL=false&CharacterEncoding=UTF-8&server=TUC
user=root
password=123456
JdbcUtil.java
里面存放的是对连接 DB 的一些配置文件,可以减少代码量
public class JdbcUtil
public static String username;
public static String password;
public static String driver;
public static String url;
static
// -1.读取配置文件
InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
try
pro.load(is);
username = pro.getProperty("username");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
url = pro.getProperty("url");
// 0.加载驱动
Class.forName(driver);
catch (Exception e)
e.printStackTrace();
public static Connection getConnection()
// 1.连接数据库
Connection conn = null;
try
conn = DriverManager.getConnection(url, username, password);
catch (SQLException throwables)
throwables.printStackTrace();
return conn;
public static void close(ResultSet rs, Statement stmt,Connection conn)
// 5.关闭连接
try
if(rs!=null)
rs.close();
catch (SQLException throwables)
throwables.printStackTrace();
finally
try
if (stmt!=null)
stmt.close();
catch (SQLException throwables)
throwables.printStackTrace();
finally
try
if (conn!=null)
conn.close();
catch (SQLException throwables)
throwables.printStackTrace();
Dao 层
dao 里面存放的是对 DB 进行操作的一些代码
IUserDao.java 里面存放的是对 DB 进行操作的一些代码的接口
public interface IUserDao
// 添加用户
public boolean add(User user);
// 查询
public User query(User user);
// 根据名字查询
public User queryUserByName(String name);
// 根据ID_NUMBER查
public User queryUserByNumber(String number);
UserDao.java 里面的就是实现 IUserDao.java 的代码,对 DB 进行操作
public class UserDao implements IUserDao
@Override
public boolean add(User user)
…………
return user;
@Override
public User query(User user)
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
User loginuser = null;
try
// 1.连接数据库
conn = JdbcUtil.getConnection();
// 2.获取Statement对象:将sql语句传给数据库服务器执行
String sql = "select * from T_USER where USERNAME = ? and PASSWORD = ?";
stmt = conn.prepareStatement(sql);
// 2.5.注入参数
stmt.setString(1,user.getUsername());
stmt.setString(2,user.getPassword());
// 3.执行sql,获取返回结果
rs = stmt.executeQuery();
// 4.处理结果集
if(rs.next())
Integer id = rs.getBigDecimal("id")==null?null:rs.getBigDecimal("id").intValue();
String un = rs.getString("username");
String password = rs.getString("password");
Integer sex = rs.getString("sex")==null?null:rs.getBigDecimal("sex").intValue();
String idNumber = rs.getString("ID_NUMBER");
String tel = rs.getString("tel");
String addr = rs.getString("addr");
Integer type = rs.getString("type")==null?null:rs.getBigDecimal("type").intValue();
loginuser = new User(id,un,password,sex,idNumber,tel,addr,type);
catch (Exception e)
e.printStackTrace();
finally
JdbcUtil.close(rs,stmt,conn);
return loginuser;
@Override
public User queryUserByName(String name)
…………
return user;
@Override
public User queryUserByNumber(String number)
…………
return user;
里面就是对 DB 进行增删改查等操作
Service 层
IUserService.java 里面存放的是实现 UserService.java 里面的接口
public interface IUserService
// 添加用户
public boolean register(User user);
// 登录
public User login(User user);
// 根据名字查询
public User queryUserByName(String name);
// 根据ID_NUMBER查
public User queryUserByNumber(String number);
UserService.java 里面存放的是实现 IUserService.java 接口里面的方法,申明一个 Dao 的成员,然后使用该 Dao 成员调用 Dao 里面的方法。
public class UserService implements IUserService
private UserDao userDao;
public void setUserDao(UserDao userDao)
this.userDao = userDao;
public UserDao getUserDao()
return userDao;
@Override
public boolean register(User user)
User user1 = userDao.queryUserByName(user.getUsername());
if (user1!=null) return false;
User user2 = userDao.queryUserByNumber(user.getIdNumber());
if (user2!=null) return false;
return userDao.add(user);
@Override
public User login(User user)
return userDao.query(user);
@Override
public User queryUserByName(String name)
return userDao.queryUserByName(name);
@Override
public User queryUserByNumber(String number)
return userDao.queryUserByNumber(number);
Control 层
control 里面存放的是 Servlet,与界面(view)、service进行交互。
public class UserServlet extends HttpServlet
private UserService userService;
@Override
public void init() throws ServletException
userService = new UserService();
UserDao userDao = new UserDao();
userService.setUserDao(userDao);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
doPost(req,resp);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
request.setCharacterEncoding("UTF-8");
String action = request.getParameter("action");
if("LOGIN".equalsIgnoreCase(action))
login(request,response);
else if ("REGISTER".equalsIgnoreCase(action))
register(request,response);
else
response.sendRedirect("/a1/day02/fade.jsp");
public void login(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
String username = request.getParameter("username");
String password = request.getParameter("password");
User u = new User();
u.setUsername(username);
u.setPassword(password);
User loginuser = userService.login(u);
if(loginuser!=null)
response.sendRedirect("/a1/day02/success.jsp");
else
response.sendRedirect("/a1/day02/login.jsp");
public void register(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
String[] hobbys = request.getParameterValues("hobby");
String un = request.getParameter("username");
String password = request.getParameter("password");
String usersex = request.getParameter("sex");
Integer sex = usersex==null?null:Integer.parseInt(usersex);
String idNumber = request.getParameter("id_number");
String tel = request.getParameter("tel");
String addr = request.getParameter("addr");
String usertype = request.getParameter("type");
Integer type = usertype==null?null:Integer.parseInt(usertype);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("哈哈");
Servlet生命周期 init 只会执行一次,申明 Service 层的对象一般只申明一次,以后项目上云了,如果有成千上万的人来访问你的网页,执行一次就创建一个 Service ,非常的浪费,所以为了减少内存的使用就把 Service 放入到 init 里面。
Model 层
里面存放的是实体类,对成员的 getter 与 setter 方法,有参无参的构造函数,重写toString等方法。
public class User
private int id;
private String username;
private String password;
private int sex;
private String id_number;
private String tel;
private String addr;
private int type;
public User()
public User(int id, String username, String password, int sex, String id_number, String tel, String addr, int type)
this.id = id;
this.username = username;
this.password = password;
this.sex = sex;
this.id_number = id_number;
this.tel = tel;
this.addr = addr;
this.type = type;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public int getSex()
return sex;
public void setSex(int sex)
this.sex = sex;
public String getId_number()
return id_number;
public void setId_number(String id_number)
this.id_number = id_number;
public String getTel()
return tel;
public void setTel(String tel)
this.tel = tel;
public String getAddr()
return addr;
public void setAddr(String addr)
this.addr = addr;
public int getType()
return type;
public void setType(int type)
this.type = type;
@Override
public String toString()
return "User" +
"id=" + id +
", username='" + username + '\\'' +
", password='" + password + '\\'' +
", sex=" + sex +
", id_number='" + id_number + '\\'' +
", tel='" + tel + '\\'' +
", addr='" + addr + '\\'' +
", type=" + type +
'';
或者用 lombok.jar 就可以不用写getter 与 setter 方法,有参无参的构造函数,重写toString等方法。
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User
private Integer id;
private String username;
private String password;
private Integer sex;
private String idNumber;
private String tel;
private String addr;
private Integer type;
lib 导包
lib 里面存放的是导入的一些 .jar 包。
xxx.jsp
这个不用多讲,有一点需要注意的是,from 的 action 的位置与你的 web.xml 文件对应的。
web.xml 配置
web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。 每个xml文件都有定义它书写规则的Schema文件,也就是说javaEE的定义web.xml所对应的xml Schema文件中定义了多少种标签元素,web.xml中就可以出现它所定义的标签元素,也就具备哪些特定的功能。
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.itxzw.user.control.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
servlet-mapping
servlet映射 端口映射过程就如同:你家在一个小区里B栋2410室,你朋友来找你,找到小区门口,不知道你住哪层哪号?就问守门的保安,保安很客气的告诉了他你家详细门牌,所以你朋友很轻松的找到了你家。
url-pattern
其实 url-pattern 就是说的 url 模式,就是容器在查找时根据这个模式来找到具体的servlet来执行。
servlet-name
Servlet程序起一个别名,一般是类名,作用是告诉服务器,当前配置的地址给哪个Servlet程序使用
servlet-class
java web开发中请求转发的类,就是你的类在你包下的地址。
不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!
以上是关于Servlet 架构思路(MVC)的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC基础学习之简单回顾MVC架构和Servlet的使用
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器过滤器等Web组件以及MVC架构