快速入門SSM框架——實現前後端數據交互

剛開始學習SSM框架,看着各式各樣的書,聽着大佬們錄的視頻,貌似覺得很簡單。但是親自實踐之後,就不會這麼覺得了。

從github上拉了很多個項目下來,一個個花裏胡哨,SSM框架結構命名各式各樣,一個jsp網頁或者java類就有成百上千行代碼,而我什麼都看不懂。

其實那個時候我只想搞懂SSM環境配置的邏輯,以及前端網頁如何讀取數據庫中的數據(即前端網頁顯示數據庫數據),因爲jsp網頁一旦能成功顯示數據庫中的數據,其他功能就可以以此類推,都是複製粘貼的事情了。

看不懂,沒人教,然後面向搜索引擎的編程,最後寫總結,已經是我長期以來的常態了。接着我就像做英語閱讀那樣,一行一行代碼的去查,最後把意思串起來,得到了我的理解。當然我的理解不一定準確,歡迎大佬指正。


總的思路:


前端網頁顯示數據庫數據大概分爲以下八個步驟:

  1. 在web.xml中,使用<welcome-file-list>標籤,設置默認打開的網頁  /WEB-INF/views/login/test.jsp
  2. 在該前端網頁 test.jsp 中增加一個按鈕,按鈕指向"<%=basePath%>/summary/test1.do"(<%=basePath%>後面再說)。
  3. 該地址被 web.xml 中的DispatcherServlet(攔截器)所攔截,只剩下 /summary/test1
  4. web.xml /summary/test1 傳送到 springmvc.xml ,接着springmvc.xml去掃描其管轄的包下有沒有對應的controller類。
  5. controller類(後端Java類)中找到@RequestMapping(value = "/summary/test1")的方法,執行這個方法。
  6. 在方法中,使用model.addAttribute(),像前端頁面傳送從數據庫讀取的數據,並且返回一個字符串"login/test"。
  7. 返回的字符串"login/test"在springmvc.xml的配置視圖解析器(ViewResolver)中,加上前綴"/WEB-INF/views/",加上後綴".jsp",即組成了一個完整的網頁地址,瀏覽器訪問的就是這個地址,即"/WEB-INF/views/login/test.jsp"。
  8. 前端網頁 test.jsp通過 ${msg} 來獲取後端發來的數據。

完整代碼放在最後面,先大概講一下每一步的邏輯思路


第一步

    <welcome-file-list>
        <welcome-file>/WEB-INF/views/login/test.jsp</welcome-file>
    </welcome-file-list>

<welcome-file-list>標籤字面上看起來是歡迎文件列表的意思,實際上我猜是默認加載項目的網頁的意思。配置好這個,使用Tomcat運行,就會首先加載這個界面。


第二步

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
%>
<html>
    <head>
        <title></title>
    </head>

    <body>
        <a href="<%=basePath%>/summary/test1.do">
            <button>按鈕</button>
        </a>
        <h2>${msg}</h2>
    </body>
</html>

request.getSchema()可以返回當前頁面使用的協議:  http
request.getServerName()可以返回當前頁面所在的服務器的名字:  localhost
request.getServerPort()可以返回當前頁面所在的服務器使用的端口: 8080;
request.getContextPath()可以返回當前頁面所在的應用的名字.如 /views/login/

總之就是要獲取到該項目的網絡路徑。

接着,我們使用  href="<%=basePath%>/summary/test1.do"  指向這個地址。


第三步

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

DispatcherServlet就是傳說中的攔截器,他能把第二步傳來的  /summary/test1.do  ,攔截下來,去掉後綴 .do,並且把他發送到配置文件spring.mvc。


第四步

<context:component-scan base-package="ypc.zwz.controller"/>

springmvc.xml 收到數據之後,掃描這個包下所有的類,尋找有沒有和 /summary/test1 對應的方法


第五、六步

package ypc.zwz.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import ypc.zwz.service.ArticleService;

@Controller
@RequestMapping(value = "/summary")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @RequestMapping(value = "/test1")
    public String te(@RequestParam(value = "pageCode", defaultValue = "1", required = false) int pageCode, @RequestParam(value = "pageSize", defaultValue = "3", required = false) int pageSize, HttpServletRequest request, Model model) {
        Summary summary = articleService.findById(23);
        String str = summary.getR_content();
        model.addAttribute("msg",str);
        return "login/test";
    }
}

ypc.zwz.controller包的ArticleController類中,找到與之對應的方法te();因爲這個類@RequestMapping(value = "/summary"),類下的te方法@RequestMapping(value = "/test1"),組合起來就是 /summary/test1。所以執行這個方法。

先通過articleService.findById(23);即從Serive層讀取數據庫的信息(後面會給完整代碼),再獲取Summary類中的contnt屬性,通過model.addAttribute("msg",str);方法發送至前端頁面,前端頁面可以通過"msg"這個鍵來獲取到str這個值,最後向spring.mvc返回"login/test"這個字符串。


第七步

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

springmvc.xml 接收到返回來的"login/test"字符串,利用試圖解析器(ViewResolver)加上前綴後綴,組成完整的地址"/WEB-INF/views/login/test.jsp",返回到web.xml,瀏覽器正常讀取打開,就正常打開。


第八步

代碼見第二步,在第六步中已經說明,使用msg使用這個鍵來獲取到str這個值,所以使用 ${msg} ,就獲取到了後端傳過來的str的值。


關於爲什麼要把原本的網址搞得這麼花裏胡哨,可能是爲了保密吧,比如你知道主頁的網頁地址,那麼你直接訪問這個網址,就可以跳過登入了(可能是這樣的吧,我猜的

登入地址XXXXX/views/login.jsp

主頁地址XXXXX/views/index.jsp

那我們直接訪問主頁地址,就可以跳過登入了

相反現在:

登入地址XXXXX/views/login.jsp

我們需要訪問XXXXXX.do這個後端方法,返回主頁

但是瀏覽器的網頁還是顯示XXXXXX.do

我們不知道主頁的真正地址

所以可能大概也許就起到保密的作用了。


完整代碼

test.jsp  路徑: WEB-INF/views/login/test.jsp

<%--
  Created by IntelliJ IDEA.
  User: zwz
  Date: 2020/2/17 0016
  Time: 7:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
%>
<html>
    <head>
        <title></title>
    </head>

    <body>
        <a href="<%=basePath%>/summary/test1.do">
            <button>按鈕</button>
        </a>
        <h2>${msg}</h2>
    </body>
</html>

web.xml  路徑:WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <welcome-file-list>
        <welcome-file>/WEB-INF/views/login/test.jsp</welcome-file>
    </welcome-file-list>

    <!--配置spring的字符編碼過濾器 -->
    <filter>
        <filter-name>CharacterEncoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



<!--    spring 開始-->
    <!-- 加載spring的過濾器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/spring-*.xml</param-value>
    </context-param>
   <listener><!-- 啓動web容器時,自動裝配spring-dao.xml-->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--    spring 結尾-->


    <!--配置springmvc的核心過濾器 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
<!--            容器啓動自動加載springmvc.xml  -->
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

spring-mvc.xml  路徑: src/main/resources/spring/springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/context/spring-tx.xsd
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 開啓註解掃描 -->
    <context:component-scan base-package="ypc.zwz.controller"/>

    <!-- 配置springmvc的驅動,並開啓了對JSON數據格式的支持 -->
    <mvc:annotation-driven/>

    <!-- 配置視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>


</beans>

spring-dao.xml  地址:  src/main/resources/spring/spring-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

    <!-- 配置註解掃描 -->
    <context:component-scan base-package="ypc.zwz.service"/>

    <!-- 加載數據庫配置文件 -->
    <context:property-placeholder location="classpath:resource/jdbc.properties"/>

    <!-- 數據庫連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 配置數據庫連接池屬性 -->
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- c3p0連接池私有屬性 -->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>
        <!-- 關閉連接後不自動commit -->
        <property name="autoCommitOnClose" value="false"/>
        <!-- 獲取連接超時時間 -->
        <property name="checkoutTimeout" value="10000"/>
        <!-- 當獲取連接失敗後重新連接的次數 -->
        <property name="acquireRetryAttempts" value="2" />
    </bean>

    <!-- 配置SqlSessionFactory對象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入數據庫連接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 啓用mybatis的別名配置 -->
        <property name="typeAliasesPackage" value="ypc.zwz.pojo"/>
        <!-- 掃描Mapper層的配置文件 -->
        <property name="mapperLocations" value="classpath:ypc/zwz/mapper/*.xml"/>
    </bean>

    <!-- 啓用mybatis的接口代理開發模式(接口和Xml配置必須同名,並且在同一目錄下) -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="ypc.zwz.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

</beans>

ArticleController.java  路徑 :src/main/java/cn/ypc/controller/ArticleController.java

package ypc.zwz.controller;

import ypc.zwz.pojo.Summary;
import ypc.zwz.service.ArticleService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/summary")
public class ArticleController {
    private ArticleService articleService;
    @RequestMapping(value = "/test1")
    public String te(@RequestParam(value = "pageCode", defaultValue = "1", required = false) int pageCode,@RequestParam(value = "pageSize", defaultValue = "3", required = false) int pageSize,HttpServletRequest request,Model model) {
        Summary summary = articleService.findById(23);
        String str = summary.getR_content();
        model.addAttribute("msg",str);
        return "login/test";
    }
}

其餘代碼和我之前做的周總結雲盤代碼一致,開源,點擊這裏查看

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