Servlet 架构思路(MVC)

2年前 (2022) 程序员胖胖胖虎阿
283 0 0

Servlet 架构思路(MVC)

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

目录

目录下的结构

配置文件

Dao 层

Service 层

Control 层

Model 层

lib 导包

web.xml 配置


目录下的结构

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

Servlet 架构思路(MVC)

配置文件

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 架构思路(MVC)

 servlet-mapping

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

url-pattern

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

servlet-name

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

servlet-class

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

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

Servlet 架构思路(MVC)

版权声明:程序员胖胖胖虎阿 发表于 2022年9月9日 上午10:40。
转载请注明:Servlet 架构思路(MVC) | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...