文章目錄
前言
該文章用來歸納一下,並且給需要的人做參考,希望可以幫助到大家,如果有什麼寫的不對的,可以指出來共同討論共同進步。
不用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的坑,其他的我在上面的代碼註釋和解釋都或多或少說了:
- ajax和form結合使用時候要十分注意(建議不要結合使用),因爲我一開始不是用ajax,用form表單提交請求,所以後面改用ajax時候,ajax代碼中前面提交寫成$(‘form’).submit結果就發生405錯誤,一直提示不支持post,這個問題也是我花最多時間解決的,具體原因參照:用ajax模擬post請求報錯 “405 Method not allowed”,解決方法可以用這篇文章的,也可以像我一樣直接刪除form表單。
- 用form標籤時,ajax的contentType是不支持application/json數據的,要用application/x-www-form-urlencoded,這裏可能是我的button標籤是type=submit類型,所以不可以,因爲我看到很多教程都用application/json,所以具體情況具體分析。關於post的提交數據方式參考:四種常見的 POST 提交數據方式
- 後端返回值是json對象類型,如果ajax中要處理json對象,這不用做轉換,否則需要轉換成字符串形式,參考:json.stringify()的妙用,json.stringify()與json.parse()的區別
- 另外controller獲取ajax傳的值時用的註解:@RequestBody和@RequestParam區別
- 還有controller層拿到json值的原理@ResponseBody ResponseEntity