1. 程式人生 > >IDEA +SpringMVC+Mybatis+JSON+AJAX(登入註冊)應用

IDEA +SpringMVC+Mybatis+JSON+AJAX(登入註冊)應用

整體結構 :
這裡寫圖片描述

建議:
    一般先寫服務端層,最後寫客戶端層(客戶端層可以先不用管)

第一步:main下建立java檔案:

建立相應格式資料夾
main-Java下(控制層、資料訪問層、實體類、業務層、輔助方法層)
resopurces下(sql寫mapper資料夾、SpringContext配置檔案)

第二步:編寫配置檔案(pom.xml):

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>spring-mybatis-study</groupId> <artifactId>com.study</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version
>
<name>com.study Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version
>
<scope>test</scope> </dependency> <!--Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.9.RELEASE</version> </dependency> <!-- spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <!-- mysql 連線--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.4</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.3</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <!--jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!--mybatis-spring整合包,這樣就可以通過spring配置bean的方式進行mybatis配置了, 不然需要單獨使用mybatis的配置--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.14.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.14.RELEASE</version> </dependency><!-- https://mvnrepository.com/artifact/commons-codec/commons-codec 下面加密包--> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <!-- https://mvnrepository.com/artifact/org.webjars.bower/jquery --> <dependency> <groupId>org.webjars.bower</groupId> <artifactId>jquery</artifactId> <version>3.2.1</version> </dependency> </dependencies> <build> <finalName>com.study</finalName> </build> </project>

第二步:配置StringContext檔案(內部包括資料庫連線、掃描元件等)
這裡寫圖片描述

<?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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    <bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/note?user=root&amp;password=root"/>
    </bean>
    <bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dbcp">
        </property>
        <property name="mapperLocations" value="classpath:sql/*.xml"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="org.tarena.note.dao"/>
        <!-- 自動注入sqlsessionfactory-->
    </bean>
    <!--開啟掃描,掃描Controller,Service元件-->
    <context:component-scan base-package="org.tarena.note"/>
    <!--handlermapping,支援@RequestMapping,@ResponseBody-->
    <mvc:annotation-driven/>
</beans>

第三步:編寫mapper檔案:

這裡寫圖片描述

其中<mapper namespace="org.tarena.note.dao.UserDao">語句為介面呼叫路徑,將來用於被呼叫的介面
resultType:結果型別;
parameterType:傳入引數型別

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.tarena.note.dao.UserDao">
    <select id="findByName" parameterType="string" resultType="org.tarena.note.entity.User">
          select * from cn_user
            where cn_user_name=#{name}
    </select>
    <insert id="save" parameterType="org.tarena.note.entity.User">
            insert into cn_user(cn_user_id,cn_user_name,cn_user_password,cn_user_token,cn_user_nick)
            value(#{cn_user_id},#{cn_user_name},#{cn_user_password},#{cn_user_token},#{cn_user_nick})
    </insert>
</mapper>

第四步:編寫實體類
這裡寫圖片描述
(user)與資料庫名稱相對應

package org.tarena.note.entity;

import java.io.Serializable;

public class User  implements Serializable{
    private String cn_user_id;
    private String cn_user_name;
    private String cn_user_token;
    private String cn_user_nick;
    private String cn_user_password;

    public String getCn_user_id() {
        return cn_user_id;
    }

    public void setCn_user_id(String cn_user_id) {
        this.cn_user_id = cn_user_id;
    }


    public String getCn_user_desc() {
        return cn_user_nick;
    }

    public void setCn_user_desc(String cn_user_desc) {
        this.cn_user_nick = cn_user_nick;
    }

    public String getCn_user_token() {

        return cn_user_token;
    }

    public void setCn_user_token(String cn_user_token) {
        this.cn_user_token = cn_user_token;
    }

    public String getCn_user_password() {

        return cn_user_password;
    }

    public void setCn_user_password(String cn_user_password) {
        this.cn_user_password = cn_user_password;
    }

    public String getCn_user_name() {
        return cn_user_name;
    }

    public void setCn_user_name(String cn_user_name) {
        this.cn_user_name = cn_user_name;
    }

}

NoteResult(我們定義一個實體類,用於返回結果):

status:我們設定狀態 0表示登陸成功 1 表示使用者名稱已被佔用 2 表示密碼錯誤
msg:   當用戶登陸不成功 ,返回對應資訊
data: 用於保留資料 ,方便以後cookie的使用
package org.tarena.note.entity;

import java.io.Serializable;

/**
 * Created by TTOP on 2018/3/24.
 */
public class NoteResult  implements Serializable{
    private int status;    //狀態
    private String msg;   //訊息
    private Object data;   //資料
    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMsg() {

        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getStatus() {

        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

}

第五步:寫資料庫介面
這裡寫圖片描述

package org.tarena.note.dao;

import org.tarena.note.entity.User;

/**
 * Created by TTOP on 2018/3/23.
 */
public interface UserDao {
    public User findByName(String name);
    public void save(User user);
}

第六步:編寫業務層(最關鍵的一步,也是最容易出錯的一部)

這裡寫圖片描述
首先編寫業務層介面,方便呼叫業務:

package org.tarena.note.service;

import org.tarena.note.entity.NoteResult;

import java.security.NoSuchAlgorithmException;

/**
 * Created by TTOP on 2018/3/24.
 */
public interface UserService {
    public NoteResult checkLogin(String name,String pwd) throws NoSuchAlgorithmException;
    public  NoteResult regist(String name, String password, String nickname) throws NoSuchAlgorithmException;
}
其次編寫相應業務:
此處:result.setData(user.getCn_user_id());//返回userID
當用戶註冊成功後返回相應ID 用於以後cookie的呼叫
此處兩個方法 一個用於註冊 一個用於登陸
package org.tarena.note.service;

import org.springframework.stereotype.Service;
import org.tarena.note.dao.UserDao;
import org.tarena.note.entity.NoteResult;
import org.tarena.note.entity.User;
import org.tarena.note.util.NoteUtil;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;


@Service  //掃描Service元件
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao; //注入
    public NoteResult checkLogin(String name,String pwd) throws NoSuchAlgorithmException {
            NoteResult result = new NoteResult();
            User user = userDao.findByName(name);
            if(user==null){
                result.setStatus(1);
                result.setMsg("使用者名稱不存在");
                return result;
            }
        //將使用者輸入的pwd密碼加密
        String md5_pwd=NoteUtil.md5(pwd);
        //與資料庫密碼比對
            if(!user.getCn_user_password().equals( md5_pwd)){
                result.setStatus(2);
                result.setMsg("密碼不正確");
                return  result;
            }
            result.setStatus(0);
            result.setMsg("使用者名稱和密碼正確");
            result.setData(user.getCn_user_id());//返回userID
            return  result;
    }

    public NoteResult regist(String name, String password, String nickname) throws NoSuchAlgorithmException {
        NoteResult result = new NoteResult();
        //檢測使用者名稱是否被佔用
        User hash_user=userDao.findByName(name);
        if(hash_user!=null){
            result.setStatus(1);
            result.setMsg("使用者名稱已被佔用");
            return  result;
        }
        User user = new User();
        user.setCn_user_name(name);
        String md5_pwd = NoteUtil.md5(password);
        user.setCn_user_password(md5_pwd);
        user.setCn_user_desc(nickname);
        String userId=NoteUtil.createId();
        user.setCn_user_id(userId);
        //呼叫userDao儲存
        userDao.save(user);
        result.setStatus(0);
        result.setMsg("註冊成功");
        return result;
    }
}

第七步:寫控制層:
這裡寫圖片描述
首先註冊

package org.tarena.note.controller.user;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.tarena.note.entity.NoteResult;
import org.tarena.note.service.UserService;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;

/**
 * Created by TTOP on 2018/3/27.
 */
@Controller
@RequestMapping("/user")
public class RegistController {
    @Resource
    private  UserService userService;
    @RequestMapping("/regist.do")
    @ResponseBody
    public NoteResult execute(String name,String password ,String nickname) throws NoSuchAlgorithmException {
           NoteResult result= userService.regist(name, password, nickname);
        return  result;
    }
}

其次登陸
(@ResponseBody 註解的作用是將controller的方法返回的物件通過適當的轉換器轉換為JSON物件返回)

package org.tarena.note.controller.user;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.tarena.note.dao.UserDao;
import org.tarena.note.entity.NoteResult;
import org.tarena.note.entity.User;
import org.tarena.note.service.UserService;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;

/**
 * Created by TTOP on 2018/3/24.
 */
@Controller 
@RequestMapping("/user")
public class LoginController {
    @Resource    
    private UserService userService;
    @RequestMapping("/login.do")
    @ResponseBody 
    public NoteResult execute(String name,String pwd) throws NoSuchAlgorithmException {
        NoteResult result = userService.checkLogin(name,pwd);
        return result;
    }
}

第八步:寫輔助功能(一般為密碼加密,攔截器等,本人此處寫的為密碼加密功能,用的時候直接呼叫即可)

package org.tarena.note.util;

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;


/**
 * Created by TTOP on 2018/3/26.
 */
public class NoteUtil {
    public static  String createId(){
        UUID uuid = UUID.randomUUID();
        return  uuid.toString();
    }
    public  static String md5(String msg) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] input = msg.getBytes();
        byte[] output = md.digest(input);
       String result= Base64.encodeBase64String(output);
        return result;
    }
    public  static  void main (String [] args) throws NoSuchAlgorithmException {
        System.out.println(md5("1234"));//測試
        System.out.println(md5("saddsasdadsa"));
    }
}


以上為服務端,接下去寫客戶端

第一步:頁面,註冊頁面的匯入(此處偷懶直接拿了別人的登陸註冊頁面)
第二步:匯入相應需要用的指令碼:
這裡寫圖片描述
第三步:編寫JS指令碼程式碼用於與服務端的互動(此處應用了AJAX 返回的是JSON物件)

此處應有cookie,當登陸成功後呼叫註冊後ID(可以拉回前面去看,請保持uid名稱的一致性),增加cookie儲存兩小時,該使用者不用再登陸

             //result是伺服器返回的json結果
                    if(result.status==0){
                        var userId = result.data;
                        addCookie("uid",userId,2);//儲存2小時
                        window.location.href="edit.html";

註冊:

$(function(){
    $("#regist_button").click(function(){
        //獲取表單資訊
        var name = $("#regist_username").val().trim();
        var nick=$("#nickname").val().trim();
        var password = $("#regist_password").val().trim();
        var final_password=$("#final_password").val().trim();
        //傳送Ajax請求
        $.ajax({
            url:"http://localhost:8080/user/regist.do",
            type:"post",
            data:{"name":name,"password":password,"nickname":nick},
            dataType:"json",
            success:function(result){
                if(result.status==0){
                    alert(result.msg);
                    $("#back").click();//觸發返回按鈕的單擊
                }else if(result.status==1){ //使用者已存在
                    $("#warning_1 span").html(result.msg);
                    $("#warning_1").show();//顯示提示資訊
                }
            }
        });
    });
})

登陸:

$(function(){
    $("#login").click(function(){
        //清空資料
        $("#count_msg").html(" ");
        $("#password_msg").html(" ");
        //檢查資料格式
        var ok =true;
        if(name==""){
            $("#count_msg").html("使用者名稱不能為空");
            ok=false;
        }2
        if(password==""){
            $("#password_msg").html("密碼不能為空");
            ok=false;
        }
        //獲取請求資料
        var name=$("#count").val().trim();
        var password = $("#password").val().trim();
        if(ok){
            //傳送Ajax請求
            $.ajax({
                url:"http://localhost:8080/user/login.do",
                type:"post",
                data:{"name":name,"pwd":password},
                dataType:"json",
                success:function(result){
                    //result是伺服器返回的json結果
                    if(result.status==0){
                        var userId = result.data;
                        addCookie("uid",userId,2);//儲存2小時
                        window.location.href="edit.html";
                    }else if (result.status==1){
                        $("#count_msg").html(result.msg);
                    }else if(result.status==2){
                        $("#password_msg").html(result.msg);
                    }
                }
            });
        }
    });
});

第四部:在此處相應頁面進行呼叫所有指令碼,和你寫的JS指令碼

<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="scripts/jquery.min.js"></script>
    <script type="text/javascript" src="scripts/cookie_util.js"></script>
    <script type="text/javascript" src="scripts/login.js"></script>
    <script type="text/javascript" src="scripts/regist.js"></script>

全域性:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="scripts/jquery.min.js"></script>
    <script type="text/javascript" src="scripts/cookie_util.js"></script>
    <script type="text/javascript" src="scripts/login.js"></script>
    <script type="text/javascript" src="scripts/regist.js"></script>
<link rel="stylesheet" href="styles/login.css"/>
</head>
    <body>
        <div class="global">
            <div class="log log_in" tabindex='-1' id='dl'>
                <dl>
                    <dt>
                        <div class='header'>
                            <h3>登&nbsp;錄</h3>
                        </div>
                    </dt>
                    <dt></dt>
                    <dt>
                        <div class='letter'>
                            使用者名稱:&nbsp;<input type="text" name="" id="count" tabindex='1'/>
                            <span id="count_msg"></span>
                        </div>
                    </dt>
                    <dt>
                        <div class='letter'>
                            密&nbsp;&nbsp;&nbsp;碼:&nbsp;<input type="password" name="" id="password" tabindex='2'/>
                           <span id="password_msg"></span>
                        </div>
                    </dt>
                    <dt>
                        <div>
                            <input type="button" name="" id="login" value='&nbsp登&nbsp錄&nbsp' tabindex='3'/>
                            <input type="button" name="" id="sig_in" value='&nbsp注&nbsp冊&nbsp' tabindex='4'/>
                        </div>
                    </dt>
                </dl>
            </div>
            <div class="sig sig_out" tabindex='-1' id='zc' style='visibility:hidden;'>
                <dl>
                    <dt>
                        <div class='header'>
                            <h3>注&nbsp;冊</h3>
                        </div>
                    </dt>
                    <dt></dt>
                    <dt>
                        <div class='letter'>
                            使用者名稱:&nbsp;<input type="text" name="" id="regist_username" tabindex='5'/>
                            <div class='warning' id='warning_1'><span>該使用者名稱不可用</span></div>
                        </div>
                    </dt>
                    <dt>
                        <div class='letter'>
                            暱&nbsp;&nbsp;&nbsp;稱:&nbsp;<input type="text" name="" id="nickname" tabindex='6'/>
                        </div>