实例演示如何以全注解的方式搭建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的使用——在线编辑和查看文章

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