Spring+Velocity+Mybatis入門(step by step)

一、開發工具

開發過程中使用的操作系統是OS X,關於軟件安裝的問題請大家移步高效的Mac環境設置
本文是我對自己學習過程的一個回顧,應該還有不少問題待改進,例如目錄的設置、編碼習慣和配置文件的處理等,請大家多多指正。
文中用到的開發工具列舉如下:

  • JDK 1.7.0_79
  • Intellij IDEA Ultimate 14
  • Mysql 5.6.25
  • Maven 3
  • Git、SourceTree

二、新建工程

1. 新建空的maven工程

第一步新建工程,選擇Maven工程,如圖1所示。注意,“create from archetype”是一些Maven的工程模板,在這裏我們爲了學習要從頭開始自己配置。

圖1 新建Maven工程
圖1 新建Maven工程

點擊next,出現設置工程座標的頁面,如圖2所示。GroupId 是公司組織的標號;ArtifactId是項目名稱;綜合來看,在src/main/java目錄下會新建對應的包結構:GroupId.ArtifactId。

圖2 設置工程座標
圖2 設置工程座標

點擊next,出現設置工程名字的界面,如圖3所示。這裏跟之前的ArtifactId一樣就可以,設置完後選擇finish完成工程構建。我們這個示例項目採用的是單模塊項目,我猜這裏是設置模塊相關的吧,還需繼續學習。

圖3 設置工程名字
圖3 設置工程名字

2. 編輯.gitignore文件

我們不需要從頭開始寫.gitignore文件,已經有人爲我們準備好了模板文件,只需要在模板文件的基礎上稍作修改即可。

首先要給IDEA安裝.gitignore插件,然後在工程名字上右擊建立.gitignore文件,通過插件可以根據項目的內容選擇需要忽略的文件或者文件夾。在這裏我選擇了三個類型:Java、JetBrains、OSX三個模板的組合文件。因爲Maven編譯生成的目錄名爲target,我又增加了target文件夾的忽略,如圖4所示。

這裏寫圖片描述
圖4 .gitignore文件示例

3. 初始化倉庫

通過SourceTree,創建本地倉庫,將目標路徑設置爲usersDemo工程的根目錄,如圖5所示。倉庫初始化完成後,我們的項目就在Git管理之下了,可以開始下一步了。

這裏寫圖片描述
圖5 初始化倉庫

三、Spring MVC支持

1. 添加Spring MVC庫以及servlet庫

首先在pom.xml文件中修改配置,通過properties標籤統一管理依賴庫的版本,方便後續更新;通過dependencies標籤管理所有的庫依賴,本次增加的配置代碼如下所示:

    <properties>
        <spring.version>4.1.7.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!-- spring support -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- jsp support -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope> <!-- 僅僅在編譯時使用 -->
        </dependency>
    </dependencies>

接下來爲項目增加Spring MVC框架支持,也就是每個web項目都應該有的web文件夾等等。具體操作如圖6和圖7所示。其中Spring MVC框架的庫已經不用下載,使用我們之前在pom中下載好的庫即可。

圖6 Add Framework Support
圖6 Add Framework Support(1)

選擇相應的Web框架和庫文件

圖7 Add Framework Support
圖7 Add Framework Support(2)

添加完成後,要對項目的目錄結構做一些調整:將web文件夾移動到src/main/目錄下,並重命名爲webapp,調整後的目錄結構如圖8所示。

這裏寫圖片描述
圖8 項目目錄結構

2. web.xml

web.xml的作用是配置DispatcherServlet,在SpringMVC項目中DispatcherServlet作爲前端控制器。服務器給用戶的接口名並不是真正的servlet類的名字,只是一個邏輯名稱,由DispatcherServlet完成這個邏輯名稱到真正的servlet類的映射過程。

在web.xml的代碼中,org.springframework.web.servlet.DispatcherServlet的實例名稱爲usersDemo,這個servlet-name 非常重要,默認情況下,DispatcherServlet在加載時會從一個機遇這個servlet名字的XML文件中加載Spring應用上下文,在這裏,因爲servlet-name是usersDemo,所以DispatcherServlet將會從usersDemo-servlet.xml文件中加載應用上下文。現在項目的目錄結構圖如圖9所示。

這裏寫圖片描述圖9 項目目錄和web.xml文件對應關係

通過servlet-mapping標籤指定由usersDemo這個DispatcherServlet實例處理哪些映射,在這裏我們設置爲“/”,即聲明該DispatcherServlet實例會吹所有的請求,包括靜態資源的請求。

最後,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_3_1.xsd"
         version="3.1">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>usersDemo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/usersDemo-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>usersDemo</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3. usersDemo-servlet.xml

DispatcherServlet需要諮詢一個或者多個處理器映射器來決定要將請求發送給哪個控制器,我們這裏常用的處理器映射器是DefaultAnnotationHandlerMapping:即將請求映射給使用@RequestMapping註解的控制器和控制器方法。

最新的Spring的發展趨勢是依靠註解來減少XML配置,因此我們在usersDemo.xml中添加下面一行配置,就可以得到Spring MVC提供的註解驅動測試

<mvc:annotation-driven/>

我們將會給控制器類添加@Controller來表明這是一個控制器類,這個類是@Component的子類,也就是說可以通過”context:component-scan標籤”來查找控制器類並將其自動註冊爲Bean。需要再usersDemo.xml中添加下面一行配置:

<context:component-scan base-package="com.alibaba.yunos.usersDemo.controller"/>

4. 控制器

經過了上一步的鋪墊,控制器的代碼比較簡單。@Controller註解告訴Spring這是一個控制器類,要將它註冊爲Bean;@RequestMapping註解告訴Spring將”/showUsers“接口,並且HTTP方法是GET的請求由showUser方法處理。

在showUser方法中我們使用servlet直接打印HTTP響應內容,很熟悉的hello系列。

UsersController的代碼列舉如下:

package com.alibaba.yunos.usersDemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by duqi on 15/8/19.
 */

@Controller
public class UsersController {

    @RequestMapping(value = "/showUser",method = RequestMethod.GET)
    public void showUser(HttpServletResponse response) throws IOException {
        response.getWriter().print("<h1>Hello SpringMVC</h1>");
        response.flushBuffer();
    }
}

5. 啓動web服務

  • 配置maven的構建過程
    在pom文件中要增加兩個配置,第一個是打包格式;第二個是build生成文件的名稱。
    相關的配置代碼爲:
<packaging>war</packaging>
<build>
    <finalName>usersDemo</finalName>
</build>
  • 配置並運行tomcat
    在IDEA中配置tomcat的步驟有下面幾步:
    (1)在屏幕右上角,選擇”Edit Configuration“,如圖10所示。
    圖10
    圖10 Edit Configuration

    (2)選擇建立一個本地的tomcat容器,如圖11所示。
    圖11
    圖11 Run/Debug Configuration

    (3)配置項目的發佈方式爲:usersDemo:war exploded,並且將應用程序上下文設置爲”/usersDemo”,如圖12所示。
    圖12
    圖12 配置部署方式和上下文環境

    (4)配置tomcat容器的安裝地址、啓動服務器後是否需要自動啓動瀏覽器、有文件修改或者檢查到新的框架時容器如何反應,我們這裏選擇”update classes and resources“,如圖13所示。
    這裏寫圖片描述
    圖13 配置tomcat服務器信息

    (5)啓動tomcat容器,URL爲:http://localhost:8080/usersDemo/showUser。
    最後的運行效果如圖所示:
    圖14
    圖14 訪問效果圖

6. 代碼提交

使用SourceTree對剛纔修改和增加的代碼進行提交,如圖15所示,對於commit message要儘量簡潔。

這裏寫圖片描述
圖15 提交commit

四、Velocity支持

Velocity的存在是爲了輔助前後端分離:後端接口開發人員可以專心於提供數據、前端人員可以使用佔位符(模板文件)暫時代替數據。渲染:將佔位符替換爲真正的變量值,並生成最終的網頁頁面。

1. 添加Velocity支持庫

首先在pom.xml中編輯,下載Velocity的支持庫,包括三個支持:Velocity、Velocity-tool、spring-context-support。
添加的依賴代碼如下:

        <!-- velocity support-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>${velocity.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>${velocity-tools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

2. 增加Velocity視圖解析器

在usersDemo-servlet.xml文件中配置Velocity視圖解析器。配置代碼如下:

       <!--規定模板文件的類型和位置-->
       <bean id="velocityConfigurer"
             class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
              <property name="resourceLoaderPath" value="/WEB-INF/templates/" />
              <property name="velocityProperties">
                     <props>
                            <prop key="input.encoding">utf-8</prop>
                            <prop key="output.encoding">utf-8</prop>
                     </props>
              </property>
       </bean>
       <!--配置附加工具,以及將後綴爲vm的文件交給下面的Resolver處理-->
       <bean id="velocityViewResolver"
             class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
              <property name="suffix" value=".vm" />
              <property name="contentType" value="text/html;charset=utf-8" />
       </bean>

3. 修改控制器代碼

控制器的作用是根據請求調用BLL層提供的Service實例,當服務接口返回處理結果後,由控制器將模型對象和邏輯視圖名稱返回。在這裏還不涉及模型數據,因此只關注邏輯視圖,解析器根據這個邏輯視圖名稱,再加上在usersDemo-servlet.xml文件中定義的視圖解析器設置,找到對應的模板文件進行渲染。
控制器的代碼如下:

package com.alibaba.yunos.usersDemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


/**
 * Created by duqi on 15/8/19.
 */

@Controller
public class UsersController {

    @RequestMapping(value = "/showUser",method = RequestMethod.GET)
    public String showUser() {
        //1.調用BLL層的服務接口
        //2.設置模型數據
        //3.返回邏輯視圖名稱
        return "showUser";
    }
}

4. 創建模板文件

現在的模板文件非常簡單,就是一句話:”hello velocity!!“,現在項目目錄結構和模板文件如圖16所示(注意路徑與usersDemo-servlet.xml中配置的對應關係)。

圖16
圖16 模板文件示例

5. 測試視圖解析器

啓動tomat服務器,運行結果如圖17所示。

這裏寫圖片描述
圖17 測試Velocity解析器

6. 代碼提交

通過SourceTree提交commit。

五、Mybatis支持

Mybatis 的着力點,則在於POJO 與SQL之間的映射關係。然後通過映射配置文件,將SQL所需的參數,以及返回的結果字段映射到指定POJO。 相對Hibernate“O/R”而言,Mybatis是一種“Sql Mapping”的ORM實現。

1. 增加Mybatis支持庫以及Mysql庫

在pom.xml文件中增加相應的支持庫,包括mybatis、mybatis-spring、commons-dbcp2、mysql-connector-java等庫。其中commons-dbcp2是用作管理數據庫連接池。
增加的配置代碼如下:


        <!-- mybatis support -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis-spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>
    </dependencies>

2. 在Mysql準備好數據庫和表

(1)建立一個數據庫mybatis用於測試;

(2)建立一張表users,各個字段的設置如圖18所示。
這裏寫圖片描述

圖18 users表結構

(3)爲表中插入初始數據,如圖19所示。
這裏寫圖片描述

圖19 users表中的數據

3. 配置數據源dataSource

數據源的配置在applicationContext.xml中完成,具體的配置代碼如下:

       <!-- 數據庫配置 -->
       <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
              <property name="username" value="databasename"/>
              <property name="password" value="yourpassword"/>
       </bean>

4. 增加數據模型POJO

在數據庫中,id字段我們設置爲自動增加。User.java的代碼如下

package com.alibaba.yunos.usersDemo.model;

/**
 * Created by duqi on 15/8/19.
 */
public class User {
    private String NAME;
    private String age;

    public String getNAME() {
        return NAME;
    }

    public void setNAME(String NAME) {
        this.NAME = NAME;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

4. 增加DAO層

要和 Spring 一起使用 MyBatis,你需要在 Spring 應用上下文中定義至少兩樣東西:一個 SqlSessionFactory 和至少一個數據映射器類。在 MyBatis-Spring 中,SqlSessionFactoryBean 是用於創建 SqlSessionFactory 的。

       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"/>
       </bean>

首先新建一個接口UserMapper,完成請求方法(getUser)到SQL語句的映射,代碼下所示:

package com.alibaba.yunos.usersDemo.mapper;

import com.alibaba.yunos.usersDemo.model.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
 * Created by duqi on 15/8/19.
 */
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{userId}")
    User getUser(@Param("userId")String userId);
}

接着在applicationContext.xml文件中增加配置,將UserMapper接口加入到Spring容器中,配置代碼如下所示:

       <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" >
              <property name="mapperInterface" value="com.alibaba.yunos.usersDemo.mapper.UserMapper"/>
              <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
       </bean>

至此,DAO和數據庫層就已經配置好了。

5. 增加Service層

首先增加UserService接口,代碼如下:

package com.alibaba.yunos.usersDemo.service;

import com.alibaba.yunos.usersDemo.model.User;
/**
 * Created by duqi on 15/8/19.
 */
public interface UserService {
    User getUser(String userId);
}

然後增加UserServiceImpl實現,代碼如下:

package com.alibaba.yunos.usersDemo.service.impl;

import com.alibaba.yunos.usersDemo.mapper.UserMapper;
import com.alibaba.yunos.usersDemo.model.User;
import com.alibaba.yunos.usersDemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by duqi on 15/8/19.
 */
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUser(String userId) {
        return this.userMapper.getUser(userId);
    }
}

在applicationContext.xml中配置UserServieImpl的實例Bean,由於已經在代碼中使用@Autiwired註解,因此不需要在配置文件中顯式得規定屬性以及提供setter函數。配置代碼如下:

       <!-- Service層的設置 -->
       <bean id="userService" class="com.alibaba.yunos.usersDemo.service.impl.UserServiceImpl"/>

6. 修改控制器代碼

控制器的邏輯依舊十分簡單,就是三個步驟:

1. 調用BLL層的Service接口

2. 設置模型數據

3. 返回邏輯視圖名稱

修改後的控制器代碼如下:

package com.alibaba.yunos.usersDemo.controller;

import com.alibaba.yunos.usersDemo.model.User;
import com.alibaba.yunos.usersDemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;


/**
 * Created by duqi on 15/8/19.
 */

@Controller
public class UsersController {
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/showUser",method = RequestMethod.GET)
    public String showUser(@RequestParam("id") String id, ModelMap modelMap) {
        //1.調用BLL層的服務接口
        User user = userService.getUser(id);
        //2.設置模型數據
        modelMap.put("user",user);
        //3.返回邏輯視圖名稱
        return "showUser";
    }
}

7. 修改模板代碼

在模板中使用數據就像使用真正的java對象的數據一樣,我們修改後的模板代碼如下:

#if(${user})
    ${user.NAME}
#else
    您查找的用戶不存在!
#end

8. 啓動Web服務開始測試

(1). http://localhost:8080/usersDemo/showUser?id=8

(2). http://localhost:8080/usersDemo/showUser?id=1

該URL對應的結果如圖20所示。

這裏寫圖片描述這裏寫圖片描述

圖20 結果展示

9. 代碼提交

至此,一個Spring+Mybatis+Velocity框架構成的簡陋的Demo就完成一個查詢功能了,通過SourceTree記錄里程碑。

我們在這一步還做了一個調整,將applicationContext.xml調整到src/main/resources文件夾下。對此我的想法是將應用程序配置文件放在resources目錄,至於是不是合理,還請各位看官討論。

六、單元測試Junit

如上所示,一個接口從前端後數據庫已經打通了,但是,每次都要等前端頁面寫好了才能開始測試?這樣效率太低了,可不可以將前後端的工作分開,讓後端人員能夠專注於提供接口,並可以及時測試?可以,單元測試。

由於控制器層是非常薄的一層,負責將傳入的URL請求傳到BLL層對應的Service實例進行處理。我們可以假定控制器層的代碼不需要測試,那麼只要Service層保證自己的接口正確就ok。Java中最流行的單元測試框架是Junit,這裏探討如何在Junit的TestCase中自動注入Service實例。
首先在pom.xml中添加測試庫支持,配置代碼如下:

        <!-- test support -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

第二,在src/test/java下新建包,與src/main下保持一致,在這裏我要測試的類是UserServiceImpl,因此新建com.alibaba.yunos.usersDemo.service。
新建測試類UserServiceImplTest,該類的代碼如下:

package com.alibaba.yunos.usersDemo.service;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.yunos.usersDemo.model.User;

/**
 * Created by duqi on 15/8/19.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:/applicationContext.xml")
public class UserServiceImplTest {
    @Autowired
    private UserService userService;

    @Test
    public void getUserTest(){
        User user = userService.getUser("1");
        Assert.assertNotNull(user);
    }
}

@RunWith(SpringJUnit4ClassRunner.class)是爲Spring 3接入Junit 4框架,從Spring 3開始提供;
@ContextConfiguration(“classpath*:/applicationContext.xml”)是加載該類中使用的Bean所在的配置文件

七、增加新的接口

根據上文第一到第六步,我們接着給這個Demo增加新的接口:addUser、allUsers和deleteUser。

1. 考慮到新增用戶或者刪除用戶之後需要重定向到”/allUsers”(避免重複提交),我們首先實現allUsers接口。

具體的步驟如下:

(1)修改DAO層

在UserMapper中增加接口getAllUsers,代碼如下:

@Select("SELECT * FROM users")
List<User> getAllUsers();

(2)修改Service層

在UserService中增加新的接口getAllUsers,代碼如下:

List<User> getAllUsers();

在UserServiceImpl中實現該接口,代碼如下:

    public List<User> getAllUsers() {
        return this.userMapper.getAllUsers();
    }

(3)修改Controller

在UserController控制器中增加allUsers接口,代碼如下:

@RequestMapping(value ="/allUsers", method = RequestMethod.GET)
public String allUsers(ModelMap modelMap){
    List<User> users = userService.getAllUsers();
    modelMap.put("users",users);
    return "allUsers";
}

(4)增加新的模板文件

在/WEB-INF/templates下增加allUsers.vm文件,內容爲:

#if(${users})
    #foreach(${user} in ${users})
        ${user.NAME}<br>
    #end
#else
    目前沒有數據!
#end

重新啓動Web服務器,輸入URL:http://localhost:8080/usersDemo/allUsers
結果如圖21所示:

這裏寫圖片描述

圖21 allUsers接口測試結果

2. 增加addUser接口的過程列舉如下

(1)修改UserMapper

@Insert("INSERT into users(NAME,age) values(#{userName},#{userAge})")
void addUser(@Param("userName")String userName, @Param("userAge")String userAge);

(2)修改UserService

void addUser(User user);

(3)修改UserServiceImpl

public void addUser(User user) {                 
    this.userMapper.addUser(user.getNAME(),user.getAge());
}

(4)修改控制器Controller

@RequestMapping(value = "/addUser", method = RequestMethod.GET)    public String addUser(@RequestParam("name")String name, @RequestParam("age")String age,ModelMap modelMap){
    User user = new User();
    user.setNAME(name);
    user.setAge(age); 
    userService.addUser(user);
    return "redirect:/allUsers";
}

啓動Web服務器運行,訪問URL:http://localhost:8080/usersDemo/addUser?name=小紅&age=15
發現有亂碼如圖22所示:

這裏寫圖片描述

圖22 出現亂碼錯誤

亂碼錯誤是WEB開發中經常遇到的問題,我的經驗是在每個數據傳輸的節點上都要保持一致,在這裏我們用UTF-8。看一下數據從前端頁面輸入到存到後臺數據庫的流程可以看到,有幾個關鍵點:頁面字符、頁面到Controller、DAO層到數據庫;最終現在的問題我發現是在頁面向Controller轉換的時候沒有強制處理,可能有問題。因此我在Contoller裏的addUser方法一開始加了一行代碼System.out.println(name);,再次運行發現終端輸出亂碼,因此確定錯誤位置。

解決錯誤的方法是:在web.xml裏增加過濾器,即當頁面向Controller映射之前要先經過該字符過濾器處理,過濾器設置的代碼如下:

    <!-- 設置字符過濾器,用於處理URL到Controller的字符設置 -->
    <filter>
        <filter-name>encodingFilter</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>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

再次運行Web服務器測試,訪問URL:localhost:8080/usersDemo/addUser?name=哈哈&age=18
發現運行結果如圖23所示:

這裏寫圖片描述

圖23 addUser接口運行成功

3. 增加deleteUser接口

要通過查詢參數給定一個id,然後BLL層根據給定的id刪除指定用戶,這裏沒有考慮到數據庫出錯的處理方式。

(1)修改UserMapper

@Delete("DELETE FROM users WHERE id = #{userId}")
void deleteUser(@Param("userId")String userId);

(2)修改UserService

void deleteUser(String userId);

(3)修改UserServiceImpl

public void deleteUser(String userId){
    this.userMapper.deleteUser(userId);
}

(4)修改UserController

@RequestMapping(value = "/deleteUser",method = RequestMethod.GET)
public String deleteUser(@RequestParam("id")String id, ModelMap modelMap){
    userService.deleteUser(id);
    return "redirect:/allUsers";
}

爲了便於驗證,將用戶的id也取出來,需要做下面兩處修改

(1)修改User

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

(2)修改allUsers.vm

#if(${users})
    #foreach(${user} in ${users})
        ${user.id},${user.NAME}<br>
    #end
#else
    目前沒有數據!
#end

代碼修改完成,啓動Web服務器,依次訪下列的URL:
http://localhost:8080/usersDemo/deleteUser?id=8
http://localhost:8080/usersDemo/deleteUser?id=9
http://localhost:8080/usersDemo/deleteUser?id=100

然後再訪問:http://localhost:8080/usersDemo/allUsers

結果截圖如圖24所示:

這裏寫圖片描述

圖24 deleteUser接口驗證

這裏有一個疑問,刪除id爲100的時候,數據庫中明顯沒有這個數據,但是後臺也沒報出異常,原因還有待我繼續學習,有知道的朋友請留言給我,非常感謝。

八、總結

寫這篇文字的最初目的是幫助自己回顧一遍前幾天學習的東西,如果能碰巧幫助後來的同學就更好了。排版還有點亂,代碼還很簡陋,希望各位朋友指點一二。

————————

參考文獻

  1. 寫給Java Web一年左右工作經驗的人
  2. Spring+Mybatis+Velocity 工程示例
  3. Spring+Mybatis+Velocity配置
  4. Spring MVC + Mybatis + Velocity + Maven + Mysql整合實例
  5. Velocity介紹及語法
  6. Mybatis教程
  7. Mybatis與Hibernate的比較
  8. JUnit與Spring的整合——JUnit的TestCase如何自動注入Spring容器託管的對象
  9. 《Spring 實戰》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章