實例演示如何以全註解的方式搭建SSM(Spring+SpringMVC+Mybatis)項目

在學習了《Spring實戰》的一些章節後,我打算寫一個項目來鍛鍊一下。在創建項目前,我希望用全註解的方式來開發。後來就知道,debug掉的頭髮,都是前期拍腦袋進的水——網上關於註解的資料也太少了吧!!!
經過千辛萬苦後,我終於順利完成了項目的搭建:)
項目的源代碼地址:https://github.com/FuGaZn/SpringBlog
歡迎給個star哦 ( ̄∇ ̄)

概述

首先介紹一下這個SpringBlog項目:
本項目基於Spring+SpringMVC+Mybatis的技術框架,實現個人博客的登入登出、管理文章、在線編寫和發佈文章、瀏覽博客等基本功能。
在一步步搭建項目的過程中,你將學習到:

  • DispatcherServlet的配置
  • Web界面訪問的配置
  • 用Interceptor實現攔截功能
  • 自動裝配(Auto wire)
  • Controller和Service的編寫
  • 基於Mybatis實現的Mapper接口

以上所有功能將使用註解的形式配置!
(除了使用web.xml配置對靜態資源的訪問)

博客界面示例

登陸界面:
登陸界面後臺管理界面:
在這裏插入圖片描述
撰寫文章界面:
在這裏插入圖片描述博客主頁:
在這裏插入圖片描述
查看博客界面:
在這裏插入圖片描述

搭建項目

新建一個Java web項目,引入Maven框架,將pom.xml的內容配置好就完成了基本的搭建。

項目結構:
在這裏插入圖片描述在這裏插入圖片描述本項目採用Maven來管理,pom.xml文件內容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <packaging>war</packaging>
    <groupId>com.fjx.blog.spring</groupId>
    <artifactId>SpringBlog</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.16</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20170516</version>
        </dependency>

        <!--spring依賴-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--springMVC依賴-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.3.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
        <!--springMVC依賴結束-->
    </dependencies>
</project>

編寫Java web Config文件

java web cofig配置類是xml配置文件的替代,在Java類上添加@Configuration註解後,該類會被Spring識別爲配置類。

配置DispatherServlet

DispatcherServlet用於將請求發送給SpringMVC控制器(controller)DispatcherServlet 會查詢一個或多個處理器映射( handler mapping ) 來確定請求的下一站在哪裏。處理器映射會根據請求所攜帶的 URL 信息來進行決策。
DispatcherServlet的作用
MyWebInitializer.java:

package com.fjx.blog.spring.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	//根配置 和我們目前的項目無關,所有不用去關心
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {RootConfig.class};
    }

	//指定配置類
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {WebConfig.class};
    }

	//將DispatcherServlet映射到“/”,即該DispatcherServlet會處理所有的請求
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

《Spring實戰》對AbstractAnnotationConfigDispatcherServletInitializer的講解:
在這裏插入圖片描述

配置WebConfig

package com.fjx.blog.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@ComponentScan("com.fjx.blog.spring")
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    @Bean(name = "multipartResolver") // bean必須寫name屬性且必須爲multipartResolver
    //用於傳輸MultipartFile
    protected CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        commonsMultipartResolver.setMaxUploadSize(5 * 1024 * 1024);
        commonsMultipartResolver.setMaxInMemorySize(0);
        commonsMultipartResolver.setDefaultEncoding("UTF-8");
        return commonsMultipartResolver;
    }

    @Override
    //用於處理靜態資源
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resource/**").addResourceLocations("/resource/asset/");
    }
    
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

InternalResourceViewResolver用於查找JSP文件,對於傳入的視圖名稱(Controller裏@RequestMapping註解的方法返回的String是視圖名稱),爲其添加前綴和後綴,在web/webapp文件夾下查找對應的JSP文件。
例如,對以下方法:

    @RequestMapping({"/index","/"})
    public String index(Model model){
        return "home/index";
    }

InternalResourceViewResolver接收到“/home/index”字符串後,拼接前綴後綴得“/WEB-INF/views/home/index.jsp”。
注意:setPrefix方法裏的/WEB-INF/views/不能寫成WEB-INF/views/,前者通過相對路徑訪問資源,後者使用絕對路徑,因此後者會出錯。

addResourceHandlers方法用於處理對靜態資源的訪問。如果不設置,訪問靜態資源會被攔截。
如果addResourceHandlers不起作用的話,可以在web.xml中配置如下內容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee" xmlns:mvc="http://www.springframework.org/schema/mvc"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>SpringBlog</display-name>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
        <url-pattern>*.css</url-pattern>
        <url-pattern>*.woff</url-pattern>
        <url-pattern>*.svg</url-pattern>
        <url-pattern>*.ttf</url-pattern>
        <url-pattern>*.woff2</url-pattern>
        <url-pattern>*.eot</url-pattern>
        <url-pattern>*.otf</url-pattern>
        <url-pattern>*.ico</url-pattern>
        <url-pattern>*.gif</url-pattern>
        <url-pattern>*.jpg</url-pattern>
        <url-pattern>*.png</url-pattern>
    </servlet-mapping>
</web-app>

RootConfig.java:

package com.fjx.blog.spring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages = {"com.fjx.blog.spring"},
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class))
public class RootConfig {
}

配置SecurityConfig.java以實現對登陸狀態的判斷

package com.fjx.blog.spring.config;

import com.fjx.blog.spring.interceptor.SecurityInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class SecurityConfig extends WebMvcConfigurationSupport {
    @Bean
    public SecurityInterceptor securityInterceptor() {
        return new SecurityInterceptor();
    }
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(securityInterceptor());
        registration.excludePathPatterns("/home/*"); //排除對該路徑的攔截
        registration.excludePathPatterns("/");
        registration.excludePathPatterns("/login");
        registration.addPathPatterns("/admin/*"); //添加對該路徑的攔截
        registration.addPathPatterns("/admin");
    }
}

SecurityInterceptor.java的內容:

package com.fjx.blog.spring.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws IOException {
        //這裏根據session的用戶來判斷角色的權限,根據權限來轉發不同的頁面
        if(request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/login");
            return false;
        }
        return true;
    }
}

在第一次訪問被SecurityConfig攔截的界面時,因爲session裏的user屬性不存在,所以會重定向到login界面。登陸後,添加user屬性,再次訪問這些界面時,就不會被重定向了。

配置Mybatis:

在resources文件夾下建立properties文件,添加如下內容:

server.port=8080
# 數據庫連接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springblog
# 用戶名
spring.datasource.username=root
# 密碼
spring.datasource.password=123456
# 數據庫驅動
spring.datasource.driver=com.mysql.jdbc.Driver

#mybatis設置相關
mybatis.type.alias.package=com.bdqn.lyrk.ssm.study.entity
logging.leve.com.fjx.blog.spring.mapper=debug 
mybatis.configuration.mapUnderscoreToCamelCase=true

添加PropertiesConfig.java:

package com.fjx.blog.spring.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource("classpath:application.properties")
public class PropertiesConfig {
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.driver}")
    private String driver;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${mybatis.type.alias.package}")
    private String mybatisTypeAliasPackage;

    public String getUrl() {
        return url;
    }

    public String getDriver() {
        return driver;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
    
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
        return new PropertySourcesPlaceholderConfigurer();
    }
}

添加MyBatisConfig.java:

package com.fjx.blog.spring.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan("com.fjx.blog.spring.mapper")
public class MyBatisConfig {

    @Autowired
    PropertiesConfig propertiesConfig;

    @Bean
    //如果項目運行後報“Error querying database.  Cause: java.lang.NullPointerExceptio”這樣的錯誤,你或許要檢查一下這裏的配置,看看是不是url或者driverClassName爲空
    public DataSource dataSource(PropertiesConfig propertiesConfig) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(propertiesConfig.getUsername());
        dataSource.setPassword(propertiesConfig.getPassword());
        dataSource.setUrl(propertiesConfig.getUrl());
        dataSource.setDriverClassName(propertiesConfig.getDriver());
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception  {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        //不能用new PropertiesConfig()的方式引入參數,否則得不到變量
        sessionFactory.setDataSource(dataSource(propertiesConfig));
        return sessionFactory.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
        return dataSourceTransactionManager;

    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        return propertySourcesPlaceholderConfigurer;
    }

}

在以上所有文件都配置完畢後,我們就可以開發具體頁面啦!是不是很激動呢,如果你是第一次開發SpringMVC項目,可能會覺得上面的配置很繁瑣,但是如果你接觸過用XML文件進行配置的話,那肯定會覺得上面的配置太簡單了。
而且接下來,當我們配置Controller、Service、Mapper時,只需要在類上添加註解就可以完成了,不用在辛辛苦苦寫完java文件後,還要在xml文件裏進行添加或修改。

接下來讓我們以登陸操作爲例,從數據庫到jsp頁面,自底向上一條龍講述其中的全部操作。

登陸:Mapper->Service->Controller->JSP

Mapper

我們先在數據庫中建立一張表,名字爲users(在IDEA裏可以圖形化操作)

-- auto-generated definition
CREATE TABLE users
(
  id              INT AUTO_INCREMENT
    PRIMARY KEY,
  ukey            VARCHAR(255) NULL,
  name            VARCHAR(255) NULL,
  password        VARCHAR(255) NULL,
  CONSTRAINT user_uid_uindex
  UNIQUE (id)
)
  ENGINE = InnoDB;

然後創建對應的User.java:

package com.fjx.blog.spring.entity;

public class User {
    private int id;
    private String name; //暱稱
    private String ukey; //用戶身份識別key,登陸使用
    private String password;
    
	//還有一系列getter和setter方法,別忘了哦。在IDEA裏,同時摁住Alt和Insert鍵,可以一鍵添加全部getter和setter方法哦
}

配置UserMapper.java:

package com.fjx.blog.spring.mapper;

import com.fjx.blog.spring.entity.User;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;

import java.util.List;

@Mapper
@Component(value = "userMapper")
public interface UserMapper {

    @Select("select * from users")
    List<User> selectAll();

    @Select("select * from users where ukey = #{ukey}")
    List<User> selectUserByKey(String ukey);

    @Insert("insert into users values(#{user.id},#{user.ukey},#{user.name},#{user.password},#{user.userLastLoginIp})")
    @Options(useGeneratedKeys = true)
    int save(@Param("user") User user);
}

@Mapper註解表明該類是一個Mybatis Mapper
@Select/@Insert註解等用來操作sql語句。在傳入對象參數時,在參數前使用@Param註解,否則會報 xxx not found錯誤。
Mybatis的註解詳細用法可以參照:MyBatis常用11種註解

創建UserService和UserServiceImpl文件:

package com.fjx.blog.spring.service;

import com.fjx.blog.spring.entity.User;

public interface UserService {
    User getUserByKey(String key);

    void save(User user);
}

package com.fjx.blog.spring.service.impl;

import com.fjx.blog.spring.entity.User;
import com.fjx.blog.spring.mapper.UserMapper;
import com.fjx.blog.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User getUserByKey(String key) {
        List<User> users = userMapper.selectUserByKey(key);
        if (users == null || users.size() == 0){
            return null;
        }else
            return users.get(0);

    }

    public void save(User user) {
        int i = userMapper.save(user);
    }
}

可以看到UserServiceImpl實現自UserServcie接口,@Service註解要放在UserServiceImpl上
使用@AutoWired註解來爲UserMapper自動裝配

創建LoginController.java:

package com.fjx.blog.spring.controller.admin;

import com.fjx.blog.spring.entity.User;
import com.fjx.blog.spring.service.UserService;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author fujiaxing
 * 登陸登出功能
 */
@Controller
public class LoginController {
    @Autowired
    UserService userService;

    @RequestMapping({"/login","/"})
    public String login(){
        return "/admin/login";
    }

    @RequestMapping(value = "/loginVerify",method = RequestMethod.POST)
    @ResponseBody
    public String loginVerify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap();
        String userkey = request.getParameter("ukey");
        String password = request.getParameter("password");
        String rememberme = request.getParameter("rememberme");
        User user = userService.getUserByKey(userkey);
        if (user == null) {
            map.put("code", 0);
            map.put("msg", "用戶名無效!");
        } else if (!user.getPassword().equals(password)) {
            map.put("code", 0);
            map.put("msg", "密碼錯誤!");
        } else {
            System.out.println("登陸成功");
            //登錄成功
            map.put("code", 1);
            map.put("msg", "");
            //添加session
            request.getSession().setAttribute("user", user);
            if (rememberme != null) {
                //創建兩個Cookie對象
                Cookie keyCookie = new Cookie("ukey", userkey);
                //設置Cookie的有效期爲3天
                keyCookie.setMaxAge(60 * 60 * 24 * 3);
                Cookie pwdCookie = new Cookie("password", password);
                pwdCookie.setMaxAge(60 * 60 * 24 * 3);
                response.addCookie(keyCookie);
                response.addCookie(pwdCookie);
            }
          //  user.setUserLastLoginTime(new Date());
            user.setUserLastLoginIp(getIpAddr(request));
            userService.save(user);
        }

        String result = new JSONObject(map).toString();
        return result;
    }

    @RequestMapping(value = "/logOut",method = RequestMethod.GET)
    @ResponseBody
    public String loginOut(HttpServletRequest request, HttpServletResponse response){
        request.getSession().removeAttribute("user");
        Map<String, Object> map = new HashMap();
        map.put("code", 1);
        map.put("msg", "");

        String result = new JSONObject(map).toString();
        return result;
    }
}

可以看到,在LoginController裏,自動裝配的對象是UserService, 而不是UserServiceImpl
login()方法上註解配置了映射“/login”,對應的jsp文件則是/WEB-INF/views/admin/login.jsp
上文提到,我們使用session裏的user屬性判斷用戶是否需要登陸,在執行登陸操作後,我們調用request.getSession().addAttribute()方法添加user屬性。在登出系統後,我們調用request.getSession().removeAttribute()方法刪除user屬性

後端的所有類和方法都寫好啦,接下來我們就可以編寫前端界面和js代碼了。
新建一個/admin/login.jsp文件,添加如下代碼:

<body>
 	<%
        String username = "", password = "";
        Cookie[] cookies = request.getCookies();
        if (cookies!=null){
            for (int i = 0; i < cookies.length; i++) {//對cookies中的數據進行遍歷,找到用戶名、密碼的數據
                if ("ukey".equals(cookies[i].getName())) {
                    username = cookies[i].getValue();
                } else if ("password".equals(cookies[i].getName())) {
                    password = cookies[i].getValue();
                }
            }
        }
    %>
    <form name="loginForm" id="loginForm" method="post">
        <input type="text" placeholder="用戶名" name="username" id="user_login" class="input" value="<%=username%>" size="20" required/>
        <input type="password" placeholder="密碼" name="password" id="user_pass" class="input" value="<%=password%>" size="20" required/>
        <p class="forgetmenot"><label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="1" checked /> 記住密碼</label></p>
        <a class="submit">登陸
            <input type="button" name="wp-submit" id="submit-btn" value="登錄" />
        </a>
        <p id="backtoblog" style="margin-left: 160px;color: black"><a href="/index">&larr; 返回到博客</a></p>
    </form>
</body>
<script src="/resource/assets/js/jquery.min.js"></script>
<script type="text/javascript">
    $("#submit-btn").click(function () {
        var user = $("#user_login").val();
        var password = $("#user_pass").val();
        console.log(user+' '+password)
        if(user=="") {
            alert("用戶名不可爲空!");
        } else if(password==""){
            alert("密碼不可爲空!");
        } else {
            $.ajax({
                async: false,//同步,待請求完畢後再執行後面的代碼
                type: "POST",
                url: '/loginVerify',
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                data: $("#loginForm").serialize(),
                dataType: "json",
                success: function (data) {
                    if(data.code==0) {
                        alert(data.msg);
                    } else {
                        window.location.href="/admin";
                    }
                },
                error: function () {
                    alert("數據獲取失敗")
                }
            })
        }
    })

只摘取了關鍵代碼,要看全部代碼可以點擊Github: SpringBlog/Login.sjp

全部完成後,運行tomcat,就可以在localhost:8080上看到我們寫的界面啦,並且可以正常使用哦!

總結

好的,本篇文章到這裏就結束了。似乎寫了不少內容(好吧,大部分都是代碼)
註解有着比xm更簡單的配置和更好的可讀性,使用得當的話會大大減輕springmvc開發的複雜度和代碼量。
本文也未涉及深層次的spring知識,主要還是以一個簡單的登陸流程爲例,講一下如何以全註解的方式來開發一個springmvc項目。
如果對這個簡單的個人博客框架有興趣的話,可以關注https://github.com/FuGaZn/SpringBlog
SpringMVC相對於SpringBoot來說,開發起來還是太複雜了。所以這個博客項目僅用於熟悉springmvc註解配置的用法,不會搭建爲成熟的博客系統。

博客的在線編輯功能使用了Editormd,如果想了解Editormd的用法,可以看:Editormd的使用——在線編輯和查看文章

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