從.Net到Java學習第十一篇——SpringBoot登陸實現

從.Net到Java學習系列目錄javascript

經過前面10篇文章的學習,相信咱們對SpringBoot已經有了一些瞭解,那麼如何來驗證咱們的學習成果呢?固然是經過作項目來證實啦!因此從這一篇開始我將會對以前本身作的.net項目用java來重寫。這一篇,咱們來現實登陸模塊。css

一提到登陸,咱們首先想到的基本的功能點就有以下:html

輸入:用戶名、密碼、驗證碼。html5

登陸成功後,跳轉到後臺。若是未登陸直接訪問後臺,將會跳轉到登陸頁面。java

這裏暫不考慮複雜的登陸實現。mysql

技術選型,沿用前面用到的知識點。那麼這裏較之於以前的文章,新用到的一個就是圖片驗證碼,一個就是權限攔截器了。jquery

一、新建spring boot web項目,具體配置信息如pom.xml所示:git

<?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>

    <groupId>com.yujie</groupId>
    <artifactId>website</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>website</name>
    <description>通用角色權限管理系統</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--集成druid,使用鏈接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>
        <!-- 分頁插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--單元測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--熱部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- mybatis generator 自動生成代碼插件 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>


</project>
View Code

二、準備數據庫、數據表。這裏只用一張用戶表t_user.sqlgithub

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50717
Source Host           : localhost:3306
Source Database       : rightcontrol

Target Server Type    : MYSQL
Target Server Version : 50717
File Encoding         : 65001

Date: 2018-07-13 11:19:03
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `t_user`
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `Id` int(4) NOT NULL AUTO_INCREMENT,
  `UserName` varchar(20) DEFAULT NULL COMMENT '用戶名(登陸)',
  `RealName` varchar(20) DEFAULT NULL COMMENT '姓名',
  `PassWord` char(32) DEFAULT NULL COMMENT '密碼',
  `RoleId` int(4) DEFAULT NULL COMMENT '角色ID',
  `Status` bit(1) DEFAULT NULL COMMENT '狀態',
  `CreateOn` datetime DEFAULT NULL COMMENT '建立時間',
  `UpdateOn` datetime DEFAULT NULL COMMENT '修改時間',
  `CreateBy` int(4) DEFAULT NULL COMMENT '建立者',
  `UpdateBy` int(4) DEFAULT NULL COMMENT '修改者',
  `Gender` tinyint(4) DEFAULT NULL COMMENT '性別(0:男,1:女)',
  `Phone` varchar(11) DEFAULT NULL COMMENT '手機',
  `Email` varchar(30) DEFAULT NULL COMMENT '郵箱',
  `Remark` varchar(50) DEFAULT NULL COMMENT '備註',
  `HeadShot` varchar(50) DEFAULT NULL COMMENT '頭像',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', 'admin', '超級管理員', 'e10adc3949ba59abbe56e057f20f883e', '1', '', '0001-01-01 00:00:00', '2018-05-12 21:47:34', '0', '1', '0', '15243641131', 'zouyujie@126.com', null, '/Upload/img/mmexport1510485826478[1]_看圖王_2.jpg');
INSERT INTO `t_user` VALUES ('4', 'test', 'test', 'e10adc3949ba59abbe56e057f20f883e', '12', '', '2018-04-26 10:35:56', '2018-04-29 10:36:12', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('24', '3', '3', null, '1', '', '2018-04-29 08:42:00', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('25', '2', '2', null, '1', '', '2018-04-29 08:57:05', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('26', '34', '44', null, '1', '', '2018-04-29 08:58:31', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('27', '34', '3', null, '1', '', '2018-04-29 08:59:22', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('28', 'a', 'a', null, '1', '', '2018-04-29 09:04:29', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('29', 't', 't', null, '1', '', '2018-04-29 09:05:24', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('30', '44', '44', 'e10adc3949ba59abbe56e057f20f883e', '1', '', '2018-04-29 09:16:44', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('31', '4', '4', null, '1', '', '2018-04-29 09:17:29', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('32', '4', '4', null, '1', '', '2018-04-29 09:18:57', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('33', '23', '22', 'E10ADC3949BA59ABBE56E057F20F883E', '1', '', '2018-04-29 09:19:55', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('34', '4', '4', null, '1', '', '2018-04-29 09:32:53', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('35', '21', '21', 'e10adc3949ba59abbe56e057f20f883e', '2', '', '2018-04-29 09:33:13', '0001-01-01 00:00:00', '1', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('36', '4', '4', null, '2', '', '2018-04-29 09:33:30', '2018-04-29 17:29:18', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('37', '41', '4', 'e10adc3949ba59abbe56e057f20f883e', '1', '', '2018-04-29 09:40:58', '2018-04-29 13:10:08', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('38', '41', '4', null, '1', '', '0001-01-01 00:00:00', '2018-04-29 10:32:02', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('40', '41', '41', null, '2', '', '0001-01-01 00:00:00', '2018-04-29 10:08:50', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('41', '61', '6', null, '2', '', '0001-01-01 00:00:00', '2018-04-29 10:08:09', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('42', '451', '55', null, '1', '', '0001-01-01 00:00:00', '2018-04-29 10:31:36', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('43', '41', '41', null, '2', '', '0001-01-01 00:00:00', '2018-04-29 10:07:36', '0', null, null, null, null, null, null);
INSERT INTO `t_user` VALUES ('44', '661', '661', null, '2', '', '0001-01-01 00:00:00', '2018-04-29 10:06:52', '0', null, null, null, null, null, null);
View Code

三、對項目進行配置。我對配置項進行了詳實的註釋,若有不懂的,本身翻閱相關文檔。web

application.yml

spring:
  profiles:
    active: dev

application-dev.yml

server:
  port: 8080
spring:
  thymeleaf:
    cache: false #開發階段,建議關閉Thymeleaf的緩存
    mode: LEGACYHTML5 #使用遺留的html5以去掉對html標籤的校驗
  datasource:
    name: demo
    url: jdbc:mysql://127.0.0.1:3306/RightControl?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
    username: root
    password: yujie
    # 使用druid數據源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    filters: stat
    maxActive: 20 # 最大活躍數
    initialSize: 5 # 初始化數量
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20

mybatis:
  mapper-locations: classpath:mapping/*.xml  #Locations of Mapper xml config file.
  type-aliases-package: com.yujie.dao  #Packages to search for type aliases. (Package delimiters are ",; \t\n")

#pagehelper分頁插件
pagehelper:
    helperDialect: mysql
    reasonable: true #pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最後一頁
    supportMethodsArguments: true #支持經過 Mapper 接口參數來傳遞分頁參數
    #用於從對象中根據屬性名取值,能夠配置 pageNum,pageSize,count,pageSizeZero,reasonable。
    #不配置映射的用默認值,默認值爲pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
    params: count=countSql

四、自動生成mybatis相關的配置,具體如何生成這個能夠參考我前面的文章。從.Net到Java學習第三篇——spring boot+mybatis+mysql

在自動生成好的mybatis配置中,咱們還須要本身擴展一個方法CheckLogin用於校驗用戶名和密碼是否正確。

咱們首先修改UserModelMapper類,須要注意的是checkLogin方法中的參數前面必定要記得添加@Param,由於mybatis很坑的一個地方,是對於單個參數,你不須要添加@Param,對於多個參數你必需要添加@Param,不然會報錯,提示找不到參數。

@Component
public interface UserModelMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(UserModel record);

    int insertSelective(UserModel record);

    UserModel selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(UserModel record);

    int updateByPrimaryKey(UserModel record);
    //add
    UserModel checkLogin(@Param("username") String username,@Param("password") String password);
}

接下來修改UserModelMapper.xml,在其中添加一個checkLogin

  <sql id="Base_Column_List">
Id, UserName, RealName, PassWord, RoleId, Status, CreateOn, UpdateOn, CreateBy, UpdateBy,
Gender, Phone, Email, Remark, HeadShot
</sql>


<select id="checkLogin" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from t_user where username=#{username,jdbcType=VARCHAR} and password=#{password,jdbcType=VARCHAR} </select>

五、增長驗證碼的實現類ValidateCode

package com.yujie.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * 驗證碼生成器
 *
 * @author
 */
public class ValidateCode {
    // 圖片的寬度。
    private int width = 160;
    // 圖片的高度。
    private int height = 40;
    // 驗證碼字符個數
    private int codeCount = 5;
    // 驗證碼干擾線數
    private int lineCount = 150;
    // 驗證碼
    private String code = null;
    // 驗證碼圖片Buffer
    private BufferedImage buffImg = null;

    // 驗證碼範圍,去掉0(數字)和O(拼音)容易混淆的(小寫的1和L也能夠去掉,大寫不用了)
    private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 默認構造函數,設置默認參數
     */
    public ValidateCode() {
        this.createCode();
    }

    /**
     * @param width  圖片寬
     * @param height 圖片高
     */
    public ValidateCode(int width, int height) {
        this.width = width;
        this.height = height;
        this.createCode();
    }

    /**
     * @param width     圖片寬
     * @param height    圖片高
     * @param codeCount 字符個數
     * @param lineCount 干擾線條數
     */
    public ValidateCode(int width, int height, int codeCount, int lineCount) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        this.lineCount = lineCount;
        this.createCode();
    }

    public void createCode() {
        int x = 0, fontHeight = 0, codeY = 0;
        int red = 0, green = 0, blue = 0;

        x = width / (codeCount + 2);//每一個字符的寬度(左右各空出一個字符)
        fontHeight = height - 2;//字體的高度
        codeY = height - 4;

        // 圖像buffer
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        // 生成隨機數
        Random random = new Random();
        // 將圖像填充爲白色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        // 建立字體,能夠修改成其它的
        Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
//        Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);
        g.setFont(font);

        for (int i = 0; i < lineCount; i++) {
            // 設置隨機開始和結束座標
            int xs = random.nextInt(width);//x座標開始
            int ys = random.nextInt(height);//y座標開始
            int xe = xs + random.nextInt(width / 8);//x座標結束
            int ye = ys + random.nextInt(height / 8);//y座標結束

            // 產生隨機的顏色值,讓輸出的每一個干擾線的顏色值都將不一樣。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            g.setColor(new Color(red, green, blue));
            g.drawLine(xs, ys, xe, ye);
        }

        // randomCode記錄隨機產生的驗證碼
        StringBuffer randomCode = new StringBuffer();
        // 隨機產生codeCount個字符的驗證碼。
        for (int i = 0; i < codeCount; i++) {
            String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
            // 產生隨機的顏色值,讓輸出的每一個字符的顏色值都將不一樣。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            g.setColor(new Color(red, green, blue));
            g.drawString(strRand, (i + 1) * x, codeY);
            // 將產生的四個隨機數組合在一塊兒。
            randomCode.append(strRand);
        }
        // 將四位數字的驗證碼保存到Session中。
        code = randomCode.toString();
    }

    public void write(String path) throws IOException {
        OutputStream sos = new FileOutputStream(path);
        this.write(sos);
    }

    public void write(OutputStream sos) throws IOException {
        ImageIO.write(buffImg, "png", sos);
        sos.close();
    }

    public BufferedImage getBuffImg() {
        return buffImg;
    }

    public String getCode() {
        return code.toLowerCase();
    }
}
View Code

這裏須要注意的是假設咱們要讓驗證碼大小寫不敏感,那麼須要code.toLowerCase();對生成的驗證碼字符串進行轉換。

六、新增一個ajax對象類AjaxResult

package com.yujie.util;

public class AjaxResult {
    /// <summary>
    /// 操做結果類型
    /// </summary>
    public Object state;
    /// <summary>
    /// 獲取 消息內容
    public String message;
    /// <summary>
    /// 獲取 返回數據
    /// </summary>
    public Object data;

    public Object getState() {
        return state;
    }

    public void setState(Object state) {
        this.state = state;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
    public static AjaxResult ok(String msg){
        AjaxResult model=new AjaxResult();
        model.setMessage(msg);
        model.state="success";
        return model;
    }
    public static AjaxResult error(String msg){
        AjaxResult model=new AjaxResult();
        model.setMessage(msg);
        model.state="fail";
        return model;
    }
}
View Code

七、添加控制器LoginController

@Controller
@RequestMapping("/login")
public class LoginController extends BaseController {
    @Autowired
    IUserService userService;
    @GetMapping("")
    public String login(Model model){
        model.addAttribute("title","後臺管理系統");
        return render("login");
    }
    @ResponseBody
    @PostMapping("/CheckLogin")
    public AjaxResult CheckLogin(@RequestParam String username, @RequestParam String password, @RequestParam String code,
                                 HttpServletRequest request,
                                 HttpServletResponse response){
        Object objCode=request.getSession().getAttribute("code");
        String _code=objCode.toString().toLowerCase();
        if(!code.equals(_code)){
           return AjaxResult.error("驗證碼錯誤,請從新輸入!");
        }
        UserModel userModel=userService.CheckLogin(username,password);
        if(userModel==null) {
            return AjaxResult.error("用戶名或密碼,請從新輸入!");
        }else {
            request.getSession().setAttribute("userinfo",userModel);
            return AjaxResult.ok("成功");
        }
    }
    /**
     * 響應驗證碼頁面
     * @return
     */
    @GetMapping(value="/GetAuthCode")
    public String validateCode(HttpServletRequest request, HttpServletResponse response) throws Exception{
        // 設置響應的類型格式爲圖片格式
        response.setContentType("image/jpeg");
        //禁止圖像緩存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        HttpSession session = request.getSession();

        ValidateCode vCode = new ValidateCode(120,40,4,100);
        session.setAttribute("code", vCode.getCode());
        vCode.write(response.getOutputStream());
        return null;
    }
}

考慮到一些公共的信息,我添加了一個控制器的父類BaseController

public abstract class BaseController {
    public static String THEME = "admin";
    public BaseController title(HttpServletRequest request, String title) {
        request.setAttribute("title", title);
        return this;
    }
    /**
     * 主頁的頁面主題
     * @param viewName
     * @return
     */
    public String render(String viewName) {
        return THEME + "/" + viewName;
    }
    public String render_404() {
        return "comm/error_404";
    }
    protected WebSiteModel GetWebSiteModel(){
        WebSiteModel model=new WebSiteModel();
        model.setSiteName("網站後臺管理系統");
        return model;
    }
    protected UserModel GetUserInfo(HttpServletRequest request){
        HttpSession session = request.getSession();
        if (null == session) {
            return null;
        }
        return (UserModel)session.getAttribute("userinfo");
    }
}

八、實現服務層,添加IUserService接口,接口的命名我沿用C#的規範首字母用I

public interface IUserService extends IBaseService<UserModel> {
    UserModel CheckLogin(String username, String password);
}

九、添加接口的實現類UserService

package com.yujie.service.impl;

import com.yujie.dao.UserModelMapper;
import com.yujie.model.UserModel;
import com.yujie.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService implements IUserService {
    @Autowired
    UserModelMapper userModelMapper;
    @Override
    public UserModel CheckLogin(String username, String password) {
        return userModelMapper.checkLogin(username,password);
    }
}

接觸java的時間不長,發現一個頗有意思的想象,不知道是不是寫java默認約定,那就是實現類都是單獨用一個叫作impl的包封裝。

十、剩下的就是View了,

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>快速開發平臺</title>
    <link th:href="@{/fonts/iconfont.css}" rel="stylesheet" />
    <link th:href="@{/css/login.css}" rel="stylesheet" />
    <script th:src="@{/js/jquery-1.10.2.min.js}"></script>
    <script th:src="@{/js/jquery.cookie.js}"></script>
    <script th:src="@{/js/jquery.md5.js}"></script>
    <!--[if lte IE 8]>
    <div id="errorie"><div>您還在使用老掉牙的IE,正常使用系統前請升級您的瀏覽器到 IE8以上版本 <a target="_blank" href="http://windows.microsoft.com/zh-cn/internet-explorer/ie-8-worldwide-languages">點擊升級</a>&nbsp;&nbsp;強烈建議您更改換瀏覽器:<a href="http://down.tech.sina.com.cn/content/40975.html" target="_blank">谷歌 Chrome</a></div></div>
    <![endif]-->
</head>
<body>
<div style="position: absolute; z-index: 999; top: 20px; left: 20px; color: #fff; font-size: 13px; line-height: 22px;">
    用戶名 admin,密碼 123456,請勿在系統內發表不文明信息
</div>
<div class="wrapper">
    <div class="container">
        <div class="logo">
            <i class="iconfont icon-ditu"></i>
            <h1><span>登陸</span><span th:text="${title}" th:remove="tag"></span></h1>
        </div>
        <form class="form">
            <div class="row">
                <input id="txt_account" type="text" placeholder="用戶名">
                <i class="fa fa-user"></i>
            </div>
            <div class="row">
                <input id="txt_password" type="password" placeholder="登陸密碼">
                <i class="fa fa-key"></i>
            </div>
            <div class="row">
                <input id="txt_code" maxlength="4" type="text" placeholder="驗證碼" style="width: 190px; float: left;">
                <div style="width: 110px; float: right; padding-top: 14px; padding-left: 14px;">
                    看不清?<a id="switchCode" href="javascript:void();" style="text-decoration: none;">換一張</a>
                    <img id="imgcode" class="authcode" th:src="@{/login/GetAuthCode}" width="80" height="25" />
                </div>
            </div>
            <div class="row">
                <button id="login_button" type="button"><span>登陸</span></button>
            </div>
            <div class="row">
            </div>
        </form>
        <div class="login_tips"></div>
    </div>
    <ul class="bg-bubbles">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>
<div class="copyright">
    <a href="@ViewBag.SiteDomain" style="text-decoration:none;color:#fff;" target="_blank">@ViewBag.CopyRight 開發團隊出品</a>
    <br>
    適用瀏覽器:IE8以上、360、FireFox、Chrome、Safari、Opera、傲遊、搜狗、世界之窗.
</div>
<script type="text/javascript">
    (function ($) {
        $.login = {
            formMessage: function (msg) {
                $('.login_tips').find('.tips_msg').remove();
                $('.login_tips').append('<div class="tips_msg"><i class="fa fa-question-circle"></i>' + msg + '</div>');
            },
            loginClick: function () {
                var $username = $("#txt_account");
                var $password = $("#txt_password");
                var $code = $("#txt_code");
                if ($username.val() == "") {
                    $username.focus();
                    $.login.formMessage('請輸入用戶名');
                    return false;
                } else if ($password.val() == "") {
                    $password.focus();
                    $.login.formMessage('請輸入登陸密碼。');
                    return false;
                } else if ($code.val() == "") {
                    $code.focus();
                    $.login.formMessage('請輸入驗證碼。');
                    return false;
                } else {
                    $("#login_button").attr('disabled', 'disabled').find('span').html("loading...");
                    $.ajax({
                        url: "/login/CheckLogin",
                        data: { username: $.trim($username.val()), password: $.md5($.trim($password.val())), code: $.trim($code.val()) },
                        type: "post",
                        dataType: "json",
                        success: function (data) {
                            if (data.state == "success") {
                                $("#login_button").find('span').html("登陸成功,正在跳轉...");
                                window.setTimeout(function () {
                                    window.location.href = "/home";
                                }, 500);
                            } else {
                                $("#login_button").removeAttr('disabled').find('span').html("登陸");
                                $("#switchCode").trigger("click");
                                $code.val('');
                                $.login.formMessage(data.message);
                            }
                        }
                    });
                }
            },
            init: function () {
                $('.wrapper').height($(window).height());
                $(".container").css("margin-top", ($(window).height() - $(".container").height()) / 2 - 50);
                $(window).resize(function (e) {
                    $('.wrapper').height($(window).height());
                    $(".container").css("margin-top", ($(window).height() - $(".container").height()) / 2 - 50);
                });
                $("#switchCode").click(function () {
                    $("#imgcode").attr("src", "/login/GetAuthCode?time=" + Math.random());
                });
                var login_error = top.$.cookie('nfine_login_error');
                if (login_error != null) {
                    switch (login_error) {
                        case "overdue":
                            $.login.formMessage("系統登陸已超時,請從新登陸");
                            break;
                        case "OnLine":
                            $.login.formMessage("您的賬號已在其它地方登陸,請從新登陸");
                            break;
                        case "-1":
                            $.login.formMessage("系統未知錯誤,請從新登陸");
                            break;
                    }
                    top.$.cookie('nfine_login_error', '', { path: "/", expires: -1 });
                }
                $("#login_button").click(function () {
                    $.login.loginClick();
                });
                document.onkeydown = function (e) {
                    if (!e) e = window.event;
                    if ((e.keyCode || e.which) == 13) {
                        document.getElementById("login_button").focus();
                        document.getElementById("login_button").click();
                    }
                }
            }
        };
        $(function () {
            $.login.init();
        });
    })(jQuery);
</script>
</body>
</html>
View Code

templates下添加admin目錄,admin目錄下,添加login.html頁面。

這樣登陸就已經實現,而後咱們還有一個權限攔截器啊。Java中經過實現HandlerInterceptor這個接口來進行過攔截功能,其實也能夠經過繼承另外一個類來實現一樣的功能,不過建議使用接口。具體類名,我一會兒想不起來啦!O(∩_∩)O哈哈~

新建類BaseInterceptor

package com.yujie.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;
@Component
public class BaseInterceptor implements HandlerInterceptor {
    private static final Logger logger = Logger.getLogger("BaseInterceptor");
    private static final String loginUrl="/login";
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        //一、請求到登陸頁面 放行
        if(request.getServletPath().startsWith(loginUrl)) {
            return true;
        }

        //二、TODO 好比退出、首頁等頁面無需登陸,即此處要放行 容許遊客的請求

        //三、若是用戶已經登陸 放行
        if(request.getSession().getAttribute("userinfo") != null) {
            //更好的實現方式的使用cookie
            return true;
        }
        //四、非法請求 即這些請求須要登陸後才能訪問
        //重定向到登陸頁面
        response.sendRedirect(request.getContextPath() + loginUrl);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
View Code

而後咱們要新建一個配置類WebMvcConfig,將這個建立的攔截器添加進來。

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Resource
    private BaseInterceptor baseInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 用於添加攔截規則, 這裏假設攔截 /url 後面的所有連接
        // excludePathPatterns 用戶排除攔截
        registry.addInterceptor(baseInterceptor).addPathPatterns("/**");
    }

    /**
     * 添加靜態資源文件,外部能夠直接訪問地址
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/upload/**").addResourceLocations("upload/");
        super.addResourceHandlers(registry);
    }
}

這樣就一切OK了,接下來看下演示效果。

 

代碼結構圖:

感受有.net基礎的話,進行java開發仍是蠻簡單的。

相關文章
相關標籤/搜索