菜鳥學SpringMVC之——SpringMVC和Servlet的區別與聯繫

SpringMVC和Servlet的區別與聯繫

Servlet:性能最好,處理Http請求的標準。

SpringMVC:開發效率高(好多共性的東西都封裝好了,是對Servlet的封裝,核心的DispatcherServlet最終繼承自HttpServlet)

這兩者的關係,就如同MyBatis和JDBC,一個性能好,一個開發效率高,是對另一個的封裝。

接下來我們分別通過SpringMVC和Servlet實現一下用戶登錄的過程,體會一下他們的區別

Servlet實現登錄

首先配置:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
	<servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.controller.LoginController</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>
</web-app>

接下來實現Model層,查詢數據庫(順便再來感受下JDBC編程的痛苦🤣)

User實體類

public class User {
    private int id;
    private String username;
    private String pwd;
//省略get、set方法
//省略JDBC鏈接數據庫的過程
public class UserDao extends BaseDao<User> {
    @Override
    public int insert(User user) {
        return 0;
    }

    @Override
    public int delete(User user) {
        return 0;
    }

    @Override
    public int update(User user) {
        return 0;
    }

    @Override
    public User select(User user) {
        Connection connection = this.getConnection();
        String sql = "select * from tb_user where username = ? and pwd = ?";
        try {
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1,user.getUsername());
            ps.setString(2,user.getPwd());
            ResultSet resultSet = ps.executeQuery();
            while (resultSet.next()) {
                User result = new User();
                result.setId(resultSet.getInt("id"));
                result.setUsername(resultSet.getString("username"));
                return result;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

service層

public class UserService implements IUserService {

    UserDao dao = new UserDao();

    @Override
    public boolean register(String username, String pwd) {
        return false;
    }

    @Override
    public User login(User user) {
        User result = dao.select(user);
        return result;
    }

}

簡易視圖層:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <form action="/web/login.do" method = "post">
    用戶名:<input type="text"name = "username"><br>
    密     碼:<input type="password"name = "password"><br>
    <input type="submit" value="登錄">
    </form>

</body>
</html>

控制層

public class LoginController extends HttpServlet {

    IUserService service = new UserService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        User user = new User();
        user.setUsername(username);
        user.setPwd(password);

        User login = service.login(user);
        if (login != null) {//如果查詢到的值不爲空,則表示登錄成功
            //正常業務這裏會將用戶信息保存在session中,然後重定向到登錄成功的頁面,這裏簡化操作,直接輸出信息
            System.out.println("登錄成功,歡迎你:" + login.getUsername() );
        } else {
            System.out.println("登錄失敗");
        }
    }
}

在這裏插入圖片描述

接下來看看SpringMVC實現用戶登錄過程

首先配置web.xml

<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <!--DispatcherServlet,這個就是Spring給我們的用來啓動web項目的容器啓動器,它可以加載ApplicationContext-->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--容器在這裏啓動,但是啓動它肯定要有個配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
    </init-param>
    <!--啓動項目時就啓動Spring容器-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--所有的請求都過DispatcherServlet-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

Spring主要也是通過DispatcherServlet實現了Servlet這個接口,又叫前端控制器,來自前端的請求會先到達這裏,它負責到後臺去匹配合適的handler。DispatcherServlet的主要工作流程如下:

前端請求到達DispatcherServlet。

前端控制器請求HandlerMappering 查找Handler。

如果查找到存在的處理器,進一步去調用service和dao層

返回結果再到controller層,渲染具體的視圖,返回結果給頁面。

具體Spring執行原理看這裏

然後加載SpringMVC的配置文件:applicationContext.xml(這些配置文件雖然看起來也挺多的,但他們只需配置一次,終身受用的)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd ">
       
    <!--掃描com.home.test包下的Controller-->
<context:component-scan base-package="com.home.test"></context:component-scan>
<mvc:annotation-driven></mvc:annotation-driven><!--mvc註解驅動-->


<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
    <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/db_foo?serverTimezone=UTC"></property>
    <property name="username" value="root"></property>
    <property name="password" value="zaq991221"></property>
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>

<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.home.test.mapper"></property>
</bean>

</beans>

然後開始掃描UserController 這個類,找到login.do。這時是通過註解來找到自己所需要的方法。

控制層:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    IUserService service;

    @RequestMapping(value = "/login.do", method = {RequestMethod.GET})
    public String login(User user) {
        User result = service.login(user);
        //登錄是否成功就看result是否有返回值
        if (result != null) {
            return "redirect:/pages/success.html";//登錄成功就重定向到成功頁面
        } else {
            return "redirect:/pages/error.html";
        }
    }
}

model層,查詢數據庫(丟棄了老舊式的JDBC,使用MyBatis框架

@Repository
public interface UserMapper {
    User findUser(@Param("user") User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--關聯Mapper定義接口-->
<mapper namespace="com.home.test.mapper.UserMapper"> <!--namespace:綁定映射器-->

    <resultMap id="UserType" type="com.home.test.entity.User" autoMapping="false">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
    </resultMap>
    <select id="findUser" resultMap="UserType">
        select * from tb_fans where username = #{user.username} and pwd=#{user.pwd}
    </select>
</mapper>

service層

@Service 
public class UserServiceImpl implements IUserService {

    @Autowired
    UserMapper mapper;

    @Override
    public User login(User user) {
        User user1 = mapper.findUser(user);
        return user1;
    }
}

對比兩個實現過程我們發現: 使用servlet的話需要每個請求都去在web.xml中配置一個servlet,並且在控制層創建一個Servlet,而且,每個Servlet只是完成了doGet、doPost方法,這就是大型的資源浪費啊。而SpringMVC中的DispatcherServlet他會攔截所有的請求,進一步去查找有沒有合適的處理器,一個前端控制器就可以。

學習參考:
https://blog.csdn.net/cleble/article/details/78018859
https://www.cnblogs.com/haolnu/p/7294533.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章