簡單Spring MVC項目搭建

1.新建Project

開發環境我使用的是IDEA,其實使用什麼都是大同小異的,關鍵是本身用的順手。javascript

首先,左上角File→New→Project。在Project頁面選擇Maven,而後勾上圖中所示的選項,在下面選擇maven-archetype→webapp選項,這個選項是Maven自動幫咱們生成一個簡單的Web程序,這樣能夠省去咱們的一些工做,不選擇這個也是徹底能夠的,這裏爲了方便直接勾選了。html

接着填寫GroupId,ArtifactId以及Version。java

接下來這個頁面,建議在Properties選項中新增一個選項:archetypeCatalog : internal,這是由於IDEA在執行archetype:generate命令時,須要指定一個archetype-catalog.xml文件,新增的這個選項就是用於指定這個文件從哪裏獲取的。默認值爲remote,下載獲取比較慢,咱們把值設爲internal,可加快速度。mysql

接着一直點到Finish,等待Project構建完成。完成後,咱們的項目結構是這個樣子。git

2. 填寫pom.xml文件

  • 首先須要添加的是properties標籤中的內容,這個標籤中表示的是咱們在pom.xml文件中能夠引用的,通常狀況下,咱們能夠把要引用的jar包的版本號放在這裏,方便之後的修改。好比,咱們要使用mysql的版本是5.1.29,就能夠在properties標籤中添加」github

3.按照SpringMVC的包結構將包建好

先在main文件夾下新建java文件夾,而後在java文件夾上右鍵新建package,這時你的IDEA多是如圖下面這樣的,即看不到有新建package這個選項。web

這是由於IDEA沒有自動識別出你的「java」文件夾下面要放類了,這時能夠打開File→Project Structure對話框,找到咱們剛剛新建的java文件夾,將其設置爲Sources類型,以下圖所示。spring

這下即可以右鍵新建package了。sql

咱們一共須要建四個包,分別是:com.tryking.dao,com.tryking.domain,com.tryking.service,com.tryking.web。下圖是建好後的結構圖。數據庫

其中,dao是用來存放操做數據庫的類的(Data Access Object),domain用於存放實體類,service用於進行真正的業務操做,web用於存放接口的處理。先暫時瞭解這麼多,具體的代碼實現咱們後面說。

4.配置SpringMVC以及JDBC等的配置文件

SpringMVC可讓咱們的開發更加方便,咱們須要在用它以前對它進行一些配置,配置文件須要在src→main→resource文件夾下新建,這裏咱們新建爲bbs-context.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

    <!-- 1.掃描類包,將標註Spring註解的類自動轉化Bean,同時完成Bean的注入 -->
    <context:component-scan base-package="com.tryking.dao"/>
    <context:component-scan base-package="com.tryking.service"/>

    <!-- 2.配置數據源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="jdbc:mysql://localhost:3306/sampledb"
          p:username="root"
          p:password="root"/>

    <!-- 3.配置Jdbc模板  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>

    <!-- 4.配置事務管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/>

    <!-- 5.經過AOP配置提供事務加強,讓service包下全部Bean的全部方法擁有事務 -->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="serviceMethod"
                      expression="(execution(* com.tryking.service..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))"/>
        <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
</beans>

如上,1用於配置Spring所需的類包地址,也就是說咱們須要告訴Spring咱們具體不一樣類型的類的位置在哪裏,能夠看到,咱們這裏將dao和service包的地址配置了進去。2用於配置數據源,即用於鏈接MySQL數據庫的內容,能夠看到咱們這裏鏈接的數據庫是sampledb,MySQL的用戶名和密碼都是root,若是你本身的MySQL端口號,用戶名以及密碼和上面不符,記得要進行修改。關於數據庫的建立咱們後面再說。3用於配置JDBC的模板,也就是用於操做數據庫的東西,直接copy上去就ok。4用於配置事務管理器,依舊copy。5用於提供事務加強,能夠看到,咱們將service包配置了進去。具體做用目前能夠不用瞭解,想了解的能夠本身百度一下看看。

5.配置servlet文件

上面咱們建立的四個包,有三個包都在4中進行配置了,還剩最後一個web包也是須要配置的,這個須要配置到servlet文件中,在WEB-INF文件夾上,右鍵新建文件,輸入「bbs-servlet.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 掃描web包,應用Spring的註解 -->
    <context:component-scan base-package="com.tryking.web"/>

    <!-- 配置視圖解析器,將ModelAndView及字符串解析爲具體的頁面 -->
    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver"
            p:viewClass="org.springframework.web.servlet.view.JstlView"
            p:prefix="/WEB-INF/jsp/"
            p:suffix=".jsp"/>
</beans>

能夠看到,咱們將新建的web包也配置進去了,這樣可讓Spring識別咱們的內容。

6.需求分析,數據庫創建

前面咱們已經將基本的環境搭建好了,下面就是考慮咱們要作什麼了,要使用Spring MVC的基本功能,咱們須要訪問數據庫,而且要將數據展示在頁面上,這樣就能夠將咱們前面建的4個包都用上了。咱們的需求是用戶訪問第一個頁面,有輸入用戶名密碼的輸入框,輸入登陸成功後,展示用戶的積分,登陸失敗則提示用戶登陸失敗。所以首先,咱們須要創建一個數據庫。

  • 新建數據庫

    打開命令行,進入mysql。執行下面的SQL語句新建一個數據庫「sampledb」。

    DROP DATABASE IF EXISTS sampledb;
    CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8;

    以下圖所示。

  • 新建表

    繼續執行如下命令,新建一個表t_user,表中含四列:user_id,user_name,password,credits。分別表示用戶的id,用戶名,密碼以及積分。

    ##建立用戶表
    CREATE TABLE t_user (
       user_id   INT AUTO_INCREMENT PRIMARY KEY,
       user_name VARCHAR(30),
       password  VARCHAR(32),
       credits INT;
    )ENGINE=InnoDB;

    以下圖所示。

  • 添加一條數據

    固然咱們還須要添加進去一條數據,以供咱們後續操做。操做內容以下。

    ##插入初始化數據
    INSERT INTO t_user (user_name,password) VALUES ('admin','123456');

    以下圖所示。

這樣咱們數據庫內容的部分就算是完成了。爲了檢驗咱們的數據庫操做是否正確,咱們能夠查詢檢驗一下咱們表中的數據,以下圖所示。

能夠看到,咱們的數據已經成功添加進去了。後續咱們只須要訪問數據庫對用戶名和密碼進行驗證便可。

7.代碼編寫

  • domain層代碼

    首先,咱們把實體類給寫出來,根據需求,咱們這裏只須要一個用戶實體就能夠了,即咱們建立一個User.java,以下圖所示。

    具體代碼以下:

    package com.tryking.domain;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private int userId;
        private String userName;
        private String password;
        private int credits;
    
        public int getUserId() {
            return userId;
        }
    
        public void setUserId(int userId) {
            this.userId = userId;
        }
    
        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 getCredits() {
            return credits;
        }
    
        public void setCredits(int credits) {
            this.credits = credits;
        }
    }

    能夠看到,咱們的User中只有四個變量,這和咱們數據庫中的數據是對應的。

  • dao層代碼

    接下來是dao層代碼的編寫,即對數據庫的訪問。根據需求,咱們須要對用戶的用戶名和密碼進行校驗,若是正確,則獲取用戶的積分,而且給它加上5分。若是用戶名密碼錯誤,則返回錯誤便可。由此可得,咱們須要寫的訪問數據庫的操做以下代碼所示,均有註釋,根據註釋去理解下就能夠。

    package com.tryking.dao;
    
    import com.tryking.domain.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowCallbackHandler;
    import org.springframework.stereotype.Repository;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    @Repository
    public class UserDao {
        private JdbcTemplate jdbcTemplate;
        private final static String MATCH_COUNT_SQL = "SELECT count(*) FROM t_user WHERE user_name =? and password=?";
        private final static String FIND_USER_SQL = "SELECT user_id,user_name,credits FROM t_user WHERE user_name=?";
        private final static String UPDATE_LOGIN_INFO_SQL = "UPDATE t_user SET credits=? WHERE user_id=?";
    
        //根據用戶名和密碼獲取匹配的數量
        public int getMatchCount(String userName, String password) {
            return jdbcTemplate.queryForObject(MATCH_COUNT_SQL, new Object[]{userName, password}, Integer.class);
        }
    
        //更新用戶的信息
        public void updateLoginInfo(User user) {
            jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL, new Object[]{user.getCredits(), user.getUserId()});
        }
    
        //根據用戶名找到用戶
        public User findUserByUserName(final String userName) {
            final User user = new User();
            jdbcTemplate.query(FIND_USER_SQL, new Object[]{userName}, new RowCallbackHandler() {
                public void processRow(ResultSet resultSet) throws SQLException {
                    user.setUserId(resultSet.getInt("user_id"));
                    user.setUserName(resultSet.getString("user_name"));
                    user.setCredits(resultSet.getInt("credits"));
                }
            });
            return user;
        }
    
        @Autowired
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    }

    值得注意的是,代碼中有兩處註解,這些都是必須的,由於Spring要根據這些信息去找對應的東西。

  • service層代碼

    在service層,是咱們真正的業務邏輯操做,咱們的邏輯就只有三個,第一,判斷用戶名密碼是否正確。第二,根據用戶名獲取用戶。第三,更新用戶的信息。所以,代碼以下:

    package com.tryking.service;
    
    import com.tryking.dao.UserDao;
    import com.tryking.domain.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class UserService {
        private UserDao userDao;
    
        //是否有匹配用戶
        public boolean hasMatchUser(String userName, String password) {
            int matchCount = userDao.getMatchCount(userName, password);
            return matchCount > 0;
        }
    
        //根據用戶名找用戶
        public User findUserByUserName(String userName) {
            return userDao.findUserByUserName(userName);
        }
    
        //登陸成功,給用戶加上5個積分
        @Transactional
        public void loginSuccess(User user) {
            user.setCredits(5 + user.getCredits());
            userDao.updateLoginInfo(user);
        }
    
        @Autowired
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    }

    代碼中依然有兩處註解,這些也都是必須的,由於Spring要根據這些信息去找對應的東西。

  • web層代碼

    最後就是web層的代碼了,根據需求,咱們須要處理的邏輯只有兩個,首先是用戶訪問咱們主頁的時候,將登錄也展示出來,用戶輸入完成,驗證成功的時候,返回登陸成功頁面。所以,咱們的代碼以下,詳情看註釋。

    package com.tryking.web;
    
    import com.tryking.domain.User;
    import com.tryking.service.UserService;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    
    @RestController
    public class LoginController {
        private UserService userService;
        private Log log = LogFactory.getLog(LoginController.class);
    
        /**
         * 用戶訪問首頁的時候,自動跳轉到「login」頁面
         *
         * @return login頁面
         */
        @RequestMapping(value = "/")
        public String loginPage() {
            log.error("********進入index.html頁面***********");
            return "login";
        }
    
        /**
         * @param request request對象
         * @param command 用戶輸入的用戶名、密碼對象
         * @return 登陸成功頁面/失敗信息
         */
        @RequestMapping(value = "/loginCheck.html")
        public ModelAndView loginCheck(HttpServletRequest request, LoginCommand command) {
            log.error("********進入loginCheck.html頁面***********");
            boolean isValidUser = userService.hasMatchUser(command.getUserName(), command.getPassword());
    
            if (!isValidUser) {
                return new ModelAndView("login", "error", "用戶名密碼不符");
            } else {
                User user = userService.findUserByUserName(command.getUserName());
                //登陸成功,加積分。
                userService.loginSuccess(user);
                request.getSession().setAttribute("user", user);
                return new ModelAndView("main");
            }
        }
    
        @Autowired
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    }

    登陸成功後,咱們作了用戶積分更新的處理。而後咱們還須要將user對象用request寫回給瀏覽器,由於咱們要將用戶信息展示給用戶。能夠看到,咱們程序中還用到了一個LoginCommand對象,這個對象中是保存網頁JSP頁面中用戶給咱們傳回來的用戶名和密碼的,JSP與咱們程序交互,咱們獲取到的就是JSP中名稱與之相同的對象,所以咱們還建立了一個LoginCommand對象,具體以下:

    package com.tryking.web;
    
    public class LoginCommand {
        private String userName;
        private String password;
    
        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;
        }
    }

    在JSP頁面中,咱們用戶名輸入框的name必須設置爲userName,密碼輸入框的nama必須設置爲password,這樣程序才能夠正常識別。

這樣,咱們的代碼就都編寫完成了,最終的程序結構圖以下。

8. 頁面編寫

上面程序都寫完了,接下來就是要寫用戶能夠訪問的頁面了,咱們的頁面很簡單,只須要有一個登陸頁面,一個登陸成功頁面便可。咱們須要在WEB-INF文件夾下建立一個JSP文件夾,而後新建兩個頁面:login.jsp以及main.jsp。以下:

首先是登陸頁面login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <title>bbs論壇登陸</title>
</head>
<body>
<form action="<c:url value="loginCheck.html"/>" method="post">
    <br><font color="#4b0082" size="12">歡迎使用bbs論壇</font><br><br>
    用戶名:
    <input type="text" name="userName">
    <br>
    <br>
    密&#12288;碼:
    <input type="password" name="password">
    <br>
    <br>
    <input type="submit" value="登陸"/>
    <input type="reset" value="重置"/>
</form>
<br>
<c:if test="${!empty error}">
    <font color="red" size="5"><c:out value="${error}"/></font>
</c:if>
</body>
</html>

能夠看到,咱們的用戶名,密碼輸入框的值分別爲userName和password,與咱們前面loginCommand是對應的。接下來是登陸成功展現頁面main.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>bbs論壇</title>
</head>
<body>
${user.userName},<br><br>歡迎您進入bbs論壇,<br><br>您當前積分爲${user.credits}。
<br><br>
<input type="button" value="退出" onClick="javascript:location.href='/bbs'">
</body>
</html>

至此,咱們的頁面就都寫完了。最後,還有一個關鍵的步驟。

9. web.xml文件配置

最後,咱們還須要作一個web.xml文件的配置,配置內容以下:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!--******************Context配置******************-->
        <param-value>classpath:bbs-context.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>bbs</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>bbs</servlet-name>
        <!-- 設置咱們的首頁 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

至此,就大功告成了。咱們一塊兒來運行一下,看看咱們的程序是否能跑起來。

咱們先用Jetty運行,首先打開Maven Projects頁面,按照下圖所示,鼠標移到左下角的位置點擊便Maven Projects頁面即可在右上角出現。

接着,咱們點開jetty標籤,雙擊jetty:run進行測試。當出現以下圖所示的內容時,說明jetty服務器已經跑起來了,咱們就能夠進行測試了。

打開網頁,輸入: http://127.0.0.1:8000/bbs/ ,就能夠成功看到咱們的登陸頁面了。

咱們鍵入用戶名:admin,密碼:1234 點擊登陸,能夠看到:

咱們鍵入用戶名:admin,密碼:12345 點擊登陸,能夠看到:

OK,大功告成,一個簡單的Spring MVC項目已經被咱們實現了。

博客地址:我是博客傳送門

項目源碼地址:我是源碼傳送門

相關文章
相關標籤/搜索