• Servlet 架构思路(MVC)


    这几天在做一个前后端分离的一个项目,采用的是 MVC 模式,对于 MVC 网上的教程杂乱无章,也没有写的较详细的,所以写了此文,本文作为一个分享文,分享本人在学习中遇到的问题以及一些自个认为好用的小技巧。

    目录

    目录下的结构

    配置文件

    Dao 层

    Service 层

    Control 层

    Model 层

    lib 导包

    web.xml 配置


    目录下的结构

    1. config
    2. jdbc.properties
    3. src
    4. com.xxx
    5. user(一般与项目名挂钩)
    6. control
    7. UserServlet.java
    8. dao
    9. impl
    10. UserDao.java
    11. IUserDao.java
    12. model
    13. User.java
    14. service
    15. impl
    16. UserService.java
    17. IUserService.java
    18. util
    19. JdbcUtil.java
    20. web
    21. web-inf
    22. web.xml
    23. lib
    24. xxx.jar
    25. xxx.jsp

    配置文件

    jdbc.properties : 开发中获得连接的4个参数(驱动、URL、用户名、密码)通常都存在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可。

    oracle 版

    1. username=itxzw
    2. password=123456
    3. driver=oracle.jdbc.OracleDriver
    4. url=jdbc:oracle:thin:@localhost:1521:orcl

    mysql 版

    1. driver=com.mysql.cj.jdbc.Driver
    2. url=jdbc:mysql://localhost:3306/db1?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false
    3. url=jdbc:mysql://localhost/db1?useSSL=false&CharacterEncoding=UTF-8&server=TUC
    4. user=root
    5. password=123456

    JdbcUtil.java

    里面存放的是对连接 DB 的一些配置文件,可以减少代码量

    1. public class JdbcUtil {
    2. public static String username;
    3. public static String password;
    4. public static String driver;
    5. public static String url;
    6. static {
    7. // -1.读取配置文件
    8. InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
    9. Properties pro = new Properties();
    10. try {
    11. pro.load(is);
    12. username = pro.getProperty("username");
    13. password = pro.getProperty("password");
    14. driver = pro.getProperty("driver");
    15. url = pro.getProperty("url");
    16. // 0.加载驱动
    17. Class.forName(driver);
    18. } catch (Exception e) {
    19. e.printStackTrace();
    20. }
    21. }
    22. public static Connection getConnection(){
    23. // 1.连接数据库
    24. Connection conn = null;
    25. try {
    26. conn = DriverManager.getConnection(url, username, password);
    27. } catch (SQLException throwables) {
    28. throwables.printStackTrace();
    29. }
    30. return conn;
    31. }
    32. public static void close(ResultSet rs, Statement stmt,Connection conn){
    33. // 5.关闭连接
    34. try {
    35. if(rs!=null){
    36. rs.close();
    37. }
    38. } catch (SQLException throwables) {
    39. throwables.printStackTrace();
    40. }finally {
    41. try {
    42. if (stmt!=null){
    43. stmt.close();
    44. }
    45. } catch (SQLException throwables) {
    46. throwables.printStackTrace();
    47. }finally {
    48. try {
    49. if (conn!=null){
    50. conn.close();
    51. }
    52. } catch (SQLException throwables) {
    53. throwables.printStackTrace();
    54. }
    55. }
    56. }
    57. }
    58. }

    Dao 层

    dao 里面存放的是对 DB 进行操作的一些代码

    IUserDao.java 里面存放的是对 DB 进行操作的一些代码的接口

    1. public interface IUserDao {
    2. // 添加用户
    3. public boolean add(User user);
    4. // 查询
    5. public User query(User user);
    6. // 根据名字查询
    7. public User queryUserByName(String name);
    8. // 根据ID_NUMBER查
    9. public User queryUserByNumber(String number);
    10. }

    UserDao.java 里面的就是实现 IUserDao.java 的代码,对 DB 进行操作

    1. public class UserDao implements IUserDao {
    2. @Override
    3. public boolean add(User user) {
    4. …………
    5. return user;
    6. }
    7. @Override
    8. public User query(User user) {
    9. Connection conn = null;
    10. PreparedStatement stmt = null;
    11. ResultSet rs = null;
    12. User loginuser = null;
    13. try {
    14. // 1.连接数据库
    15. conn = JdbcUtil.getConnection();
    16. // 2.获取Statement对象:将sql语句传给数据库服务器执行
    17. String sql = "select * from T_USER where USERNAME = ? and PASSWORD = ?";
    18. stmt = conn.prepareStatement(sql);
    19. // 2.5.注入参数
    20. stmt.setString(1,user.getUsername());
    21. stmt.setString(2,user.getPassword());
    22. // 3.执行sql,获取返回结果
    23. rs = stmt.executeQuery();
    24. // 4.处理结果集
    25. if(rs.next()){
    26. Integer id = rs.getBigDecimal("id")==null?null:rs.getBigDecimal("id").intValue();
    27. String un = rs.getString("username");
    28. String password = rs.getString("password");
    29. Integer sex = rs.getString("sex")==null?null:rs.getBigDecimal("sex").intValue();
    30. String idNumber = rs.getString("ID_NUMBER");
    31. String tel = rs.getString("tel");
    32. String addr = rs.getString("addr");
    33. Integer type = rs.getString("type")==null?null:rs.getBigDecimal("type").intValue();
    34. loginuser = new User(id,un,password,sex,idNumber,tel,addr,type);
    35. }
    36. } catch (Exception e) {
    37. e.printStackTrace();
    38. }finally {
    39. JdbcUtil.close(rs,stmt,conn);
    40. }
    41. return loginuser;
    42. }
    43. @Override
    44. public User queryUserByName(String name) {
    45. …………
    46. return user;
    47. }
    48. @Override
    49. public User queryUserByNumber(String number) {
    50. …………
    51. return user;
    52. }
    53. }

    里面就是对 DB 进行增删改查等操作

    Service 层

    IUserService.java 里面存放的是实现 UserService.java 里面的接口

    1. public interface IUserService {
    2. // 添加用户
    3. public boolean register(User user);
    4. // 登录
    5. public User login(User user);
    6. // 根据名字查询
    7. public User queryUserByName(String name);
    8. // 根据ID_NUMBER查
    9. public User queryUserByNumber(String number);
    10. }

    UserService.java 里面存放的是实现 IUserService.java 接口里面的方法,申明一个 Dao 的成员,然后使用该 Dao 成员调用 Dao 里面的方法。

    1. public class UserService implements IUserService {
    2. private UserDao userDao;
    3. public void setUserDao(UserDao userDao) {
    4. this.userDao = userDao;
    5. }
    6. public UserDao getUserDao() {
    7. return userDao;
    8. }
    9. @Override
    10. public boolean register(User user) {
    11. User user1 = userDao.queryUserByName(user.getUsername());
    12. if (user1!=null) return false;
    13. User user2 = userDao.queryUserByNumber(user.getIdNumber());
    14. if (user2!=null) return false;
    15. return userDao.add(user);
    16. }
    17. @Override
    18. public User login(User user) {
    19. return userDao.query(user);
    20. }
    21. @Override
    22. public User queryUserByName(String name) {
    23. return userDao.queryUserByName(name);
    24. }
    25. @Override
    26. public User queryUserByNumber(String number) {
    27. return userDao.queryUserByNumber(number);
    28. }
    29. }

    Control 层

    control 里面存放的是 Servlet,与界面(view)、service进行交互。

    1. public class UserServlet extends HttpServlet {
    2. private UserService userService;
    3. @Override
    4. public void init() throws ServletException {
    5. userService = new UserService();
    6. UserDao userDao = new UserDao();
    7. userService.setUserDao(userDao);
    8. }
    9. @Override
    10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    11. doPost(req,resp);
    12. }
    13. @Override
    14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. request.setCharacterEncoding("UTF-8");
    16. String action = request.getParameter("action");
    17. if("LOGIN".equalsIgnoreCase(action)){
    18. login(request,response);
    19. }else if ("REGISTER".equalsIgnoreCase(action)){
    20. register(request,response);
    21. }else{
    22. response.sendRedirect("/a1/day02/fade.jsp");
    23. }
    24. }
    25. public void login(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
    26. String username = request.getParameter("username");
    27. String password = request.getParameter("password");
    28. User u = new User();
    29. u.setUsername(username);
    30. u.setPassword(password);
    31. User loginuser = userService.login(u);
    32. if(loginuser!=null){
    33. response.sendRedirect("/a1/day02/success.jsp");
    34. }else{
    35. response.sendRedirect("/a1/day02/login.jsp");
    36. }
    37. }
    38. public void register(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
    39. String[] hobbys = request.getParameterValues("hobby");
    40. String un = request.getParameter("username");
    41. String password = request.getParameter("password");
    42. String usersex = request.getParameter("sex");
    43. Integer sex = usersex==null?null:Integer.parseInt(usersex);
    44. String idNumber = request.getParameter("id_number");
    45. String tel = request.getParameter("tel");
    46. String addr = request.getParameter("addr");
    47. String usertype = request.getParameter("type");
    48. Integer type = usertype==null?null:Integer.parseInt(usertype);
    49. response.setContentType("text/html;charset=UTF-8");
    50. response.getWriter().println("哈哈");
    51. }
    52. }

    Servlet生命周期 init 只会执行一次,申明 Service 层的对象一般只申明一次,以后项目上云了,如果有成千上万的人来访问你的网页,执行一次就创建一个 Service ,非常的浪费,所以为了减少内存的使用就把 Service 放入到 init 里面。

    Model 层

    里面存放的是实体类,对成员的 getter 与 setter 方法,有参无参的构造函数,重写toString等方法。

    1. public class User {
    2. private int id;
    3. private String username;
    4. private String password;
    5. private int sex;
    6. private String id_number;
    7. private String tel;
    8. private String addr;
    9. private int type;
    10. public User() {
    11. }
    12. public User(int id, String username, String password, int sex, String id_number, String tel, String addr, int type) {
    13. this.id = id;
    14. this.username = username;
    15. this.password = password;
    16. this.sex = sex;
    17. this.id_number = id_number;
    18. this.tel = tel;
    19. this.addr = addr;
    20. this.type = type;
    21. }
    22. public int getId() {
    23. return id;
    24. }
    25. public void setId(int id) {
    26. this.id = id;
    27. }
    28. public String getUsername() {
    29. return username;
    30. }
    31. public void setUsername(String username) {
    32. this.username = username;
    33. }
    34. public String getPassword() {
    35. return password;
    36. }
    37. public void setPassword(String password) {
    38. this.password = password;
    39. }
    40. public int getSex() {
    41. return sex;
    42. }
    43. public void setSex(int sex) {
    44. this.sex = sex;
    45. }
    46. public String getId_number() {
    47. return id_number;
    48. }
    49. public void setId_number(String id_number) {
    50. this.id_number = id_number;
    51. }
    52. public String getTel() {
    53. return tel;
    54. }
    55. public void setTel(String tel) {
    56. this.tel = tel;
    57. }
    58. public String getAddr() {
    59. return addr;
    60. }
    61. public void setAddr(String addr) {
    62. this.addr = addr;
    63. }
    64. public int getType() {
    65. return type;
    66. }
    67. public void setType(int type) {
    68. this.type = type;
    69. }
    70. @Override
    71. public String toString() {
    72. return "User{" +
    73. "id=" + id +
    74. ", username='" + username + '\'' +
    75. ", password='" + password + '\'' +
    76. ", sex=" + sex +
    77. ", id_number='" + id_number + '\'' +
    78. ", tel='" + tel + '\'' +
    79. ", addr='" + addr + '\'' +
    80. ", type=" + type +
    81. '}';
    82. }
    83. }

    或者用 lombok.jar 就可以不用写getter 与 setter 方法,有参无参的构造函数,重写toString等方法。

    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. @ToString
    5. public class User {
    6. private Integer id;
    7. private String username;
    8. private String password;
    9. private Integer sex;
    10. private String idNumber;
    11. private String tel;
    12. private String addr;
    13. private Integer type;
    14. }

    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中就可以出现它所定义的标签元素,也就具备哪些特定的功能。

    1. <servlet>
    2. <servlet-name>UserServlet</servlet-name>
    3. <servlet-class>com.itxzw.user.control.UserServlet</servlet-class>
    4. </servlet>
    5. <servlet-mapping>
    6. <servlet-name>UserServlet</servlet-name>
    7. <url-pattern>/userServlet</url-pattern>
    8. </servlet-mapping>

     servlet-mapping

    servlet映射 端口映射过程就如同:你家在一个小区里B栋2410室,你朋友来找你,找到小区门口,不知道你住哪层哪号?就问守门的保安,保安很客气的告诉了他你家详细门牌,所以你朋友很轻松的找到了你家。

    url-pattern

    其实 url-pattern 就是说的 url 模式,就是容器在查找时根据这个模式来找到具体的servlet来执行。

    servlet-name

    Servlet程序起一个别名,一般是类名,作用是告诉服务器,当前配置的地址给哪个Servlet程序使用

    servlet-class

    java web开发中请求转发的类,就是你的类在你包下的地址。

     不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!

  • 相关阅读:
    【力扣】面试经典150题——哈希表
    如何在Android Studio上发布Flutter应用
    带你一起来理解布隆过滤器,带图分析~
    买条新内存给台式机扩容,没想到出现玄学花屏
    蓝牙耳机什么牌子好?口碑最好的蓝牙耳机品牌排行
    互联世界的桥梁:探索Facebook如何连接人与人之间的纽带
    通过sudo su root不需要输入root密码,只需要输入普通账号密码
    基于改进莱维飞行和混沌映射的粒子群优化算法(Matlab代码实现)
    原生小程序小话题——事件绑定
    第四章 流程编排
  • 原文地址:https://blog.csdn.net/aasd23/article/details/126375547