spring boot+mybatis+ajax實現註冊功能和問題總結

前言

該文章用來歸納一下,並且給需要的人做參考,希望可以幫助到大家,如果有什麼寫的不對的,可以指出來共同討論共同進步。
不用aja直接跳轉頁面可以看一下 利用IDEA搭建SpringBoot項目,整合mybatis,實現簡單的登錄功能。這篇文章寫的還行,只不過可能版本有點老,有些配置不太一樣)

正文

業務場景和環境

環境

idea 2019.2+mysql5.7+spring boot2.2.2

數據庫user表:
在這裏插入圖片描述

業務場景

如圖所示,在該註冊頁面,輸入相關信息,然後通過後端的邏輯判斷一下注冊是否合法,註冊成功則跳出提示窗口顯示“註冊成功”並重定向到登錄頁面,註冊失敗則彈出註冊失敗,然後顯示出失敗的原因。
註冊頁面:
註冊頁面

下面是我的項目包(紅色框是要用到的,其他是項目別的功能)
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

詳細代碼

代碼順序我從底層到前端的順序寫,代碼裏面有註釋可以看一下:

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <!--spring-boot-starter-parent依賴pring-boot-dependencies,
    dependencies真正管理spring Boot應用裏面的所用依賴;Spring Boot的版本仲裁中心;
    以後導入依賴默認是不需要寫版本號(沒有被)-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.liaojiexin</groupId>
    <artifactId>videoweb</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>videoweb</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEnconding>UTF-8</project.build.sourceEnconding>
        <project.reporting.outputEnconding>UTF-8</project.reporting.outputEnconding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--    spring-boot-starter: spring-boot的場景啓動器;幫我們導入了web
        模塊所依賴的組件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 不是用原生的數據源,引用阿里druid數據源 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.8</version>
        </dependency>

        <!--導入配置文件處理器,配置文件進行綁定就會有提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- thymeleaf模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <!-- 這個插件,可以將應用打包成一個可執行的jar包   -->
    <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.1</version>
                <configuration>
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml配置

作用和application.properties是一樣的,這裏主要配置數據庫連接和mybatis的連接。

spring:
  datasource:
    #   數據源基本配置
    username: root  #用戶名
    password: 201314  #密碼
    driver-class-name: com.mysql.cj.jdbc.Driver   #驅動名
    url: jdbc:mysql://192.168.0.113:3306/videoweb   #路徑,這裏用虛擬機的mysql
    type: com.alibaba.druid.pool.DruidDataSource    #數據源
    #   數據源其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    #   配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml    #或寫MyMapper.xml等

DruidConfig.java

因爲application.yml使用了阿里的Druid作爲數據源,所以我們要寫一個DruidConfig配配置一下,你也可以用springboot自帶的,具體查看別人的教程

package com.liaojiexin.videoweb.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")  //綁定spring.datasource屬性,(application.yml)
    @Bean
    public DataSource druid(){      //註冊自己的數據源
        return new DruidDataSource();
    }

    //配置Druid的監控
    //1、配置一個管理後臺的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();

        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默認就是允許所有訪問

        bean.setInitParameters(initParams);
        return bean;
    }


    //2、配置一個web監控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");

        bean.setInitParameters(initParams);

        bean.setUrlPatterns(Arrays.asList("/*"));

        return  bean;
    }
}

MyMvcConfig.java

配置一下MVC,這裏主要是做請求的映射,到時候前端頁面js做跳轉頁面重定向時候可以用到(我的項目裏面也有很多地方要用到,作用很大)

package com.liaojiexin.videoweb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration  //指明當前類是一個配置類;就是來替代之前的Spring配置文件
public class MyMvcConfig implements WebMvcConfigurer {
    //所有的WebMvcConfigurerAdapter組件都會一起起作用
    @Bean //將組件註冊在容器
    public WebMvcConfigurer webMvcConfigurerAdapter() {
        WebMvcConfigurer adapter = new WebMvcConfigurer() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                //addViewController爲請求,setViewName爲路徑(spring boot設定爲templates包下的路徑,
                // 如registry.addViewController("/").setViewName("index");爲發送“/”請求時,會跳到templates/index.html路徑的頁面 )
                registry.addViewController("/").setViewName("index");               //主頁
                registry.addViewController("/index.html").setViewName("index");     //主頁
                registry.addViewController("/login").setViewName("login");          //登錄
                registry.addViewController("/register").setViewName("register");    //註冊 
            }
        };
        return adapter;
    }
}

generatorConfig.xml

配置generator,可以自動幫我創建實體類,mapper,xml映射。記得在pom.xml裏面要配置generator,另外配置中classPathEntry的location可以直接用spring boot的數據庫驅動包(如果有導入mysql的話應該就有),參考:mybatis逆向生成器配置文件中尋找mysql驅動位置classPathEntry中的location項-springboot
另外如果你的表名爲user時可能會發生生成mysql的系統user表的錯誤,詳情可見:自動生成 User 類的同時會生成 UserKey 及 UserWithBlob 類的問題的解決,不過我下面代碼已經解決該問題了。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 數據庫驅動:選擇你的本地硬盤上面的數據庫驅動包-->
    <classPathEntry  location="E:\graduation\maven\apache-maven-3.6.1\repo\mysql\mysql-connector-java\8.0.18\mysql-connector-java-8.0.18.jar"/>
    <context id="DB2Tables"  targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--數據庫鏈接URL,用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://192.168.0.113:3306/videoweb" userId="root" password="201314">
        <!-- 如果你的表名爲user,加上下面的語句可以防止生成mysql系統裏面自帶的user表-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 生成(實體)模型的包名和位置-->
        <javaModelGenerator targetPackage="com.liaojiexin.videoweb.entity" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- 生成XML映射文件的包名和位置-->
        <sqlMapGenerator targetPackage="mybatis.mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- 生成DAO接口的包名和位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.liaojiexin.videoweb.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 要生成的表 tableName是數據庫中的表名或視圖名 domainObjectName是實體類名-->
        <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>

<!-- 配置完後,還還需要進行簡單的配置,最後纔可運行,詳見https://blog.csdn.net/weixin_42685022/article/details/82215893 ;
   https://www.cnblogs.com/hudj/p/7465407.html  -->

配置完後可以啓動,前提是你的mysql裏面表要建好,用一下方式啓動,或者上面generatorConfig.xml代碼塊後面有兩行註釋的鏈接裏面的方式也可以啓動。
在這裏插入圖片描述
啓動完後會自動生成實體類,mapper.xml映射文件和dao層接口,下面貼出我的這三個文件。
(ps:這個文件生成後你可以按照自己的改,刪掉一些不必要的,我的沒刪,那些有註釋的基本上是我加上去的,其他是自動生成的)

實體類User

package com.liaojiexin.videoweb.entity;

import java.util.Date;

public class User {         //用戶
    private Integer uid;                //用戶id
    private String username;            //用戶名
    private String password;        //用戶密碼
    private String email;           //用戶郵箱
    private Date birthday;     //用戶出生日期

   省略get和set方法...
}

UserMapper接口(dao層接口)

package com.liaojiexin.videoweb.mapper;

import com.liaojiexin.videoweb.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface UserMapper {
    int deleteByPrimaryKey(Integer uid);

    int insert(User record);

    int insertSelective(User record);

    User selectByPrimaryKey(Integer uid);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
    //用戶登錄
    User userlogin(@Param("username") String username, @Param("password") String password);
    //用戶註冊
    int userInsert(User user);
    //註冊時查詢是否有重複的用戶名
    String usernameInsert(@Param("username") String username);
    //註冊時查詢是否有重複的郵箱
    String emailInsert(@Param("email") String email);
}

UserMapper.xml映射

<?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="com.liaojiexin.videoweb.mapper.UserMapper" >
  <resultMap id="BaseResultMap" type="com.liaojiexin.videoweb.entity.User" >
    <id column="uid" property="uid" jdbcType="INTEGER" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="birthday" property="birthday" jdbcType="DATE" />
  </resultMap>
  <sql id="Base_Column_List" >
    uid, username, password, email, birthday
  </sql>

<!-- resultMap要先配置,設置入參字段映射 如上的<resultMap>標籤 ,如果使用parameterType則不用配置-->
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from user
    where uid = #{uid,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from user
    where uid = #{uid,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.liaojiexin.videoweb.entity.User" useGeneratedKeys="true" keyProperty="uid">
    insert into user (username, password,
      email, birthday)
    values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
      #{email,jdbcType=VARCHAR}, #{birthday,jdbcType=DATE})
  </insert>
  <insert id="insertSelective" parameterType="com.liaojiexin.videoweb.entity.User" >
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="uid != null" >
        uid,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="email != null" >
        email,
      </if>
      <if test="birthday != null" >
        birthday,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="uid != null" >
        #{uid,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        #{email,jdbcType=VARCHAR},
      </if>
      <if test="birthday != null" >
        #{birthday,jdbcType=DATE},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.liaojiexin.videoweb.entity.User" >
    update user
    <set >
      <if test="username != null" >
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="birthday != null" >
        birthday = #{birthday,jdbcType=DATE},
      </if>
    </set>
    where uid = #{uid,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.liaojiexin.videoweb.entity.User" >
    update user
    set username = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      email = #{email,jdbcType=VARCHAR},
      birthday = #{birthday,jdbcType=DATE}
    where uid = #{uid,jdbcType=INTEGER}
  </update>
  
  <!-- 用戶登錄 -->
  <select id="userlogin" parameterType="com.liaojiexin.videoweb.entity.User" resultType="com.liaojiexin.videoweb.entity.User">
    select <include refid="Base_Column_List" /> from user where username= #{username} And password= #{password}
  </select>

  <!-- 用戶註冊 -->
  <insert id="userInsert" parameterType="com.liaojiexin.videoweb.entity.User" useGeneratedKeys="true" keyProperty="uid">
    insert into user (username, password,
      email, birthday)
    values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
      #{email,jdbcType=VARCHAR}, #{birthday,jdbcType=DATE})
  </insert>

  <!-- 註冊時查詢是否有重複的用戶名 -->
  <select id="usernameInsert" parameterType="java.lang.String" resultType="java.lang.String">
    select username from user where username=#{username} limit 1
  </select>

  <!-- 註冊時查詢是否有重複的郵箱 -->
  <select id="emailInsert" parameterType="java.lang.String" resultType="java.lang.String">
    select email from user where email=#{email} limit 1
  </select>
</mapper>

上面的基本配置基本完成,下面開始進業務邏輯編寫
因爲上面已經把數據層基本完成,所以我直接從服務層開始寫(邏輯處理儘量寫在服務層,開發規範)

UserService.java

DAO層接口

package com.liaojiexin.videoweb.service;

import com.liaojiexin.videoweb.entity.User;

import java.util.Date;
import java.util.Map;

public interface UserService{
    boolean isUserRegister(String username,String password,String repassword,String email,Date birthday, Map<String ,Object> map);     //註冊
}

UserServiceImpl.java

服務層實現類

package com.liaojiexin.videoweb.service.impl;

import com.liaojiexin.videoweb.entity.User;
import com.liaojiexin.videoweb.mapper.UserMapper;
import com.liaojiexin.videoweb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {      //處理用戶相關的服務

    @Autowired  //注入DAO
    private UserMapper userMapper;

    @Override
    public boolean isUserRegister(String username,String password,String repassword,String email,Date birthday, Map<String ,Object> map) {        //判斷用戶註冊合法性
        if (username.length()<8||username.length()>16)       //用戶名長度8-16
        {
            map.put("msgregister","用戶名長度不規範");
            return false;
        }
        else if (password.length()<8||password.length()>16)     //密碼長度8-16
        {
            map.put("msgregister","密碼長度不規範");
            return false;
        }
        else if(email.isEmpty())            //郵箱爲空
        {
            map.put("msgregister","郵箱不能爲空");
            return false;
        }
        else if (!repassword.equals(password))          //兩次密碼不同
        {
            map.put("msgregister","兩次密碼不一致");
            return false;
        }
        else if (username.equals(userMapper.usernameInsert(username)))        //用戶名已經存在
        {
            map.put("msgregister","用戶名已存在");
            return false;
        }
        else if(email.equals(userMapper.emailInsert(email)))           //郵箱已存在
        {
            map.put("msgregister","郵箱已存在");
            return false;
        }
        else
        {
            User user=new User();
            user.setUsername(username);
            user.setPassword(password);
            user.setEmail(email);
            user.setBirthday(new Date());
            userMapper.userInsert(user);
            return true;
        }
    }
}

服務層寫完,接下來寫控制層,控制層調用服務層。

RegisterController.java

package com.liaojiexin.videoweb.controller;

import com.liaojiexin.videoweb.entity.RespCode;
import com.liaojiexin.videoweb.entity.RespEntity;
import com.liaojiexin.videoweb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;

@RestController     //返回json值
public class RegisterController {       //註冊
    @Autowired
    private UserService userService;

//    在參數裏面@RequestBoby只能有一個,請求參數永遠都是一個,因爲一個request中只包含一個request body.
//    理解了這個,就會明白Spring MVC不支持多個@RequestBody。
//    @RequestParam則可以多個,兩者的差別:https://blog.csdn.net/weixin_38004638/article/details/99655322
    @PostMapping(value = "/user/register")  //和前端form表單的action相對應或者ajax對應,consumes指定處理請求的提交內容類型(Content-Type)
    public RespEntity register(@RequestParam("username") String username, @RequestParam("password") String password,
                               @RequestParam("repassword") String repassword,@RequestParam("email") String email,
                               Date birthday, Map<String ,Object> map)
    {
        boolean is=userService.isUserRegister(username,password,repassword,email,birthday,map);
        String msgregister=(String)map.get("msgregister");
        if(is==true){
            return new RespEntity(RespCode.SUCCESS);
        }
        else{
            return new RespEntity(RespCode.ERROR,msgregister);
        }
    }
}


/*spring boot+ajax前後端分離參考:
*https://blog.csdn.net/bat_xu/article/details/82597149
*https://www.cnblogs.com/yelao/p/9835707.html
*https://blog.csdn.net/ththcc/article/details/81870702
* */

這裏的控制層的返回值爲RespEntity 類,這裏是進行報文的規範,具體參考:SpringBoot學習之Json數據交互,你們也可以直接返回String值到前端頁面

RespEntity.java

package com.liaojiexin.videoweb.entity;


/*接口響應至少需要告訴使用方三項信息:狀態碼、描述、數據。其中,
數據不是每個接口必須的,如果只是一個簡單修改的動作可能就沒有必須返回數據了。
下面我們定義一個 RespEntity類來封裝我們的響應報文model:
 */
public class RespEntity {
    private int code;       //狀態
    private String msg;     //信息
    private Object data;    //數據

    public RespEntity(RespCode respCode) {
        this.code = respCode.getCode();
        this.msg = respCode.getMsg();
    }

    public RespEntity(RespCode respCode, Object data) {
        this(respCode);
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

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

    public Object getData() {
        return data;
    }

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

RespCode.java

package com.liaojiexin.videoweb.entity;

public enum RespCode {

    SUCCESS(0, "請求成功"),
    ERROR(-1, "請求失敗");

    private int code;
    private String msg;

    RespCode(int code, String msg) {
        this.code=code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

後端頁面基本完成

AJAX和html

html頁面用了bootstrap等都不用理,其他的css樣式也刪掉,主要看html代碼

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="utf-8" />
	    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
	    <meta name="viewport" content="width=device-width, initial-scale=1" />
	    <meta name="description" content="">
	    <meta name="author" content="">
		<title>註冊</title>
		
		 <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css"  type="text/css">
    
    	<!-- jQuery -->
	<script src="/js/jquery-2.1.1.js"></script>
	
	<!-- Core JavaScript Files -->  	 
    <script src="/js/bootstrap.min.js"></script>

    <script src="/js/register.js"></script>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
	    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
	    <!--[if lt IE 9]>
	        <script src="/js/html5shiv.js"></script>
	        <script src="/js/respond.min.js"></script>
	    <![endif]-->
	</head>
	<body>
            <div class="container register">
                <div class="form row">
                    <div class="form-horizontal col-md-offset-3" id="login_form">
                        <h3 class="form-title">註冊</h3>
                        <!-- th:if判斷成功才生成p標籤 -->
                        <p style="color: red;font-size: 70%;margin: 0" id="msgregister"></p>
                        <div class="col-md-9">
                            <div class="form-group">
                                <i class="fa fa-user fa-lg"></i>
                                <!--          οnkeyup="this.value=this.value.replace(/[^\w_]/g,'');"   正則表達式,限制輸入只能爲數字字母和下劃線   -->
                                <input class="form-control required"
                                       type="text" placeholder="用戶名(長度8-16,數字/字母/下劃線)" id="username" onkeyup="this.value=this.value.replace(/[^\w_]/g,'');"
                                       name="username" autofocus="autofocus" maxlength="20" required/>
                            </div>
                            <div class="form-group">
                                    <i class="fa fa-lock fa-lg"></i>
                                    <input class="form-control required"
                                           type="password" placeholder="密碼(長度8-16,數字/字母/下劃線)" id="password" onkeyup="this.value=this.value.replace(/[^\w_]/g,'');"
                                           name="password" maxlength="20" required/>
                            </div>
                            <div class="form-group">
                                    <i class="fa fa-lock fa-lg"></i>
                                    <input class="form-control required"
                                           type="password" placeholder="確認密碼(和上面相同的密碼)" onkeyup="this.value=this.value.replace(/[^\w_]/g,'');"
                                           id="repassword" name="repassword" maxlength="20" required/>
                            </div>
                            <div class="form-group">
                                    <i class="fa fa-envelope"></i>
                                    <input class="form-control required" type="email" placeholder="設置郵箱" id="email" name="email" maxlength="50" required/>
                            </div>
                            <div class="form-group col-md-offset-9">
                                <button type="submit" class="btn btn-success pull-right" name="submit">註冊</button>
                            </div>
                        </div>
                    </div>
                </div>
        </div>
	</body>
</html>
$(document).ready(function () {
    $('button[name="submit"]').click(
        function () {
            $.ajax({
                url:"/user/register",       //請求路徑,和Controller類中的@PostMapping對應
                contentType: 'application/x-www-form-urlencoded',       //客戶端實際返回的內容的內容類型,form默認application/x-www-form-urlencoded
                type: "POST",                       //請求方式
                dataType: "JSON",               //預期服務器返回的數據類型。
                data:{
                    username:$('input[name="username"]').val(),
                    password:$('input[name="password"]').val(),
                    repassword:$('input[name="repassword"]').val(),
                    email:$('input[name="email"]').val(),
                },
                success: function (data) {      //function的參數爲controller返回的json值
                    // var jsonData=JSON.stringify(data);    //stringify()用於從一個json對象解析出json字符串,alert可以完整的輸出內容,
                    // alert(jsonData);                      //但是js操作的是對象,所以此處不能轉化成字符串
                    if(data.code==0){
                        alert("註冊成功");
                        //重定向到登錄頁面,在MyMvcConfig中配置好映射 registry.addViewController("/login").setViewName("login");
                        window.location.href="/login";
                    }
                    else if(data.code==-1){
                        $("#msgregister").text(data.data);      //顯示錯誤信息
                        alert("註冊失敗");
                    }
                },
                error:function () {
                    alert("請求失敗");
                }
            });
        }
    )
})

總結

這個過程遇到很多的坑,主要還是ajax的比較麻煩,其他的都比較順利的解決了,所以下面說關於ajax的坑,其他的我在上面的代碼註釋和解釋都或多或少說了:

  1. ajax和form結合使用時候要十分注意(建議不要結合使用),因爲我一開始不是用ajax,用form表單提交請求,所以後面改用ajax時候,ajax代碼中前面提交寫成$(‘form’).submit結果就發生405錯誤,一直提示不支持post,這個問題也是我花最多時間解決的,具體原因參照:用ajax模擬post請求報錯 “405 Method not allowed”,解決方法可以用這篇文章的,也可以像我一樣直接刪除form表單。
  2. 用form標籤時,ajax的contentType是不支持application/json數據的,要用application/x-www-form-urlencoded,這裏可能是我的button標籤是type=submit類型,所以不可以,因爲我看到很多教程都用application/json,所以具體情況具體分析。關於post的提交數據方式參考:四種常見的 POST 提交數據方式
  3. 後端返回值是json對象類型,如果ajax中要處理json對象,這不用做轉換,否則需要轉換成字符串形式,參考:json.stringify()的妙用,json.stringify()與json.parse()的區別
    在這裏插入圖片描述
  4. 另外controller獲取ajax傳的值時用的註解:@RequestBody和@RequestParam區別
  5. 還有controller層拿到json值的原理@ResponseBody ResponseEntity
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章