基于SpringBoot构建电商秒杀项目代码实例

一、项目功能概述

电商秒杀需要完成的3个功能:

1.展示一个商品列表页面,我们可以从中看到可秒杀的商品列表

2.点击进入商品详情页,获取该商品的详细信息

3.秒杀时间开始后,点击进入下单确认页面,并支付成功

二、基于SpringBoot进行项目环境搭建

步骤1:创建一个maven工程,使用quickStart骨架。

步骤2:在pom.xml导入SpringBoot相关依赖。

 <?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>org.example</groupId>
  <artifactId>Spike</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Spike</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.5.RELEASE</version>
 </parent>
  <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <maven.compiler.source>1.8</maven.compiler.source>   <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencies>
   <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
   </dependency>
  </dependencies>
  <build>
   <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
    <plugins>
     <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
     <plugin>
     <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
     </plugin>
     <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
     <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <version>3.0.2</version>
     </plugin>
     <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.0</version>
     </plugin>
     <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.22.1</version>
     </plugin>
     <plugin>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.0.2</version>
     </plugin>
     <plugin>
      <artifactId>maven-install-plugin</artifactId>
      <version>2.5.2</version>
    </plugin>
     <plugin>
      <artifactId>maven-deploy-plugin</artifactId>
      <version>2.8.2</version>
     </plugin>
     <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
     <plugin>
      <artifactId>maven-site-plugin</artifactId>
      <version>3.7.1</version>
     </plugin>
     <plugin>
      <artifactId>maven-project-info-reports-plugin</artifactId>
      <version>3.0.0</version>
     </plugin>
    </plugins>
   </pluginManagement>
  </build>
 </project>

步骤3:在main/java/app中,我们对SpringBoot和SpringMVC进行简单的配置工作。掌握这几个注解的作用。

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//SpringBoot会帮我们启动tomcat,并加载默认配置
@EnableAutoConfiguration
//SpringMVC相关配置
@RestController
public class App {
  @RequestMapping("/")
  public String home(){
    //网页中输出
    return "Hello World!";
  }
  public static void main( String[] args ){
    //控制台输出
    System.out.println( "Hello World!" );
    SpringApplication.run(App.class,args);
  }
}

运行结果:

用浏览器打开http://localhost:8080/,我们可以看到页面上输出:Hello World!

同时,控制台也输出了Hello World!,以及一些Spring相关的信息。

SpringBoot小技巧:可以在resource目录下创建一个application.propeties配置文件,在其中写:server.port = 端口号来设置端口号。

步骤4:接入mybatis,首先在pom.xml添加需要的依赖(mysql,druid连接池,mybatis)

写一个plugin标签,引入对应的mybatis自动生成文件的插件 {

添加对应的依赖:mybatis generator的core(第一次使用要单独在前面导入依赖,不可直接放在plugin中),mysql数据库的解析

写一个excution标签:设置允许移动生成的文件,允许自动覆盖文件(实际工作中不可以)

写一个configuration标签:指定mybatis generator 配置文件的路径 }

1 <?xml version="1.0" encoding="UTF-8"?>
 2
 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5  <modelVersion>4.0.0</modelVersion>
 6
 7  <groupId>org.example</groupId>
 8  <artifactId>Spike</artifactId>
 9  <version>1.0-SNAPSHOT</version>
 10
 11  <name>Spike</name>
 12  <!-- FIXME change it to the project's website -->
 13  <url>http://www.example.com</url>
 14
 15 <parent>
 16  <groupId>org.springframework.boot</groupId>
 17  <artifactId>spring-boot-starter-parent</artifactId>
 18  <version>2.0.5.RELEASE</version>
 19 </parent>
 20
 21  <properties>
 22   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 23   <maven.compiler.source>1.8</maven.compiler.source>
 24   <maven.compiler.target>1.8</maven.compiler.target>
 25  </properties>
 26
 27  <dependencies>
 28   <dependency>
 29    <groupId>org.springframework.boot</groupId>
 30    <artifactId>spring-boot-starter-web</artifactId>
 31   </dependency>
 32   <dependency>
 33    <groupId>mysql</groupId>
 34    <artifactId>mysql-connector-java</artifactId>
 35    <version>5.1.6</version>
 36   </dependency>
 37   <dependency>
 38    <groupId>com.alibaba</groupId>
 39    <artifactId>druid</artifactId>
 40    <version>1.1.3</version>
 41   </dependency>
 42   <dependency>
 43    <groupId>org.mybatis.spring.boot</groupId>
 44    <artifactId>mybatis-spring-boot-starter</artifactId>
 45    <version>1.3.1</version>
 46   </dependency>
 47   <dependency>
 48    <groupId>junit</groupId>
 49    <artifactId>junit</artifactId>
 50    <version>4.11</version>
 51    <scope>test</scope>
 52   </dependency>
 53   <dependency>
 54    <groupId>org.mybatis.generator</groupId>
 55    <artifactId>mybatis-generator-core</artifactId>
 56    <version>1.3.5</version>
 57   </dependency>
 58  </dependencies>
 59
 60  <build>
 61   <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
 62    <plugins>
 63     <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
 64     <plugin>
 65      <artifactId>maven-clean-plugin</artifactId>
 66      <version>3.1.0</version>
 67     </plugin>
 68     <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
 69     <plugin>
 70      <artifactId>maven-resources-plugin</artifactId>
 71      <version>3.0.2</version>
 72     </plugin>
 73     <plugin>
 74      <artifactId>maven-compiler-plugin</artifactId>
 75      <version>3.8.0</version>
 76     </plugin>
 77     <plugin>
 78      <artifactId>maven-surefire-plugin</artifactId>
 79      <version>2.22.1</version>
 80     </plugin>
 81     <plugin>
 82      <artifactId>maven-jar-plugin</artifactId>
 83      <version>3.0.2</version>
 84     </plugin>
 85     <plugin>
 86      <artifactId>maven-install-plugin</artifactId>
 87      <version>2.5.2</version>
 88     </plugin>
 89     <plugin>
 90      <artifactId>maven-deploy-plugin</artifactId>
 91      <version>2.8.2</version>
 92     </plugin>
 93
 94     <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
 95     <plugin>
 96      <artifactId>maven-site-plugin</artifactId>
 97      <version>3.7.1</version>
 98     </plugin>
 99     <plugin>
100      <artifactId>maven-project-info-reports-plugin</artifactId>
101      <version>3.0.0</version>
102     </plugin>
103
104     <plugin>
105      <groupId>org.mybatis.generator</groupId>
106      <artifactId>mybatis-generator-maven-plugin</artifactId>
107      <version>1.3.5</version>
108      <dependencies>
109       <dependency>
110        <groupId>org.mybatis.generator</groupId>
111        <artifactId>mybatis-generator-core</artifactId>
112        <version>1.3.5</version>
113       </dependency>
114       <dependency>
115        <groupId>mysql</groupId>
116        <artifactId>mysql-connector-java</artifactId>
117        <version>5.1.6</version>
118       </dependency>
119      </dependencies>
120      <executions>
121       <execution>
122        <id>mybatis generator</id>
123        <phase>package</phase>
124        <goals>
125         <goal>generate</goal>
126        </goals>
127       </execution>
128      </executions>
129      <configuration>
130       <!--允许移动生成的文件-->
131       <verbose>true</verbose>
132       <!--允许自动覆盖文件-->
133       <overwrite>true</overwrite>
134       <!--mybatis generator 配置文件的路径-->
135       <configurationFile>
136        src/main/resource/mybatis-generator.xml
137       </configurationFile>
138      </configuration>
139     </plugin>
140
141    </plugins>
142   </pluginManagement>
143  </build>
144 </project>

步骤5:创建mysql底层的数据库与相关表格

1.创建数据库spike

2.创建一个user_info表格

3.创建一个user_password表格,并设置user_id为外键关联user_info的id

步骤6:在步骤4中,我们最后指定了mybatis generator 配置文件的路径,于是我们在指定路径(resource目录下)创建一个mybatis generator.xml,并进行如下配置:

<?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>
  <context id="mysql" targetRuntime="MyBatis3" >
    <!--数据库连接地址账号密码-->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/spike" userId="root" password="0322">
    </jdbcConnection>
    <!--生成Data Object类存放位置-->
    <javaModelGenerator targetPackage="org.example.dataobject" targetProject="src/main/java">
      <property name="enableSubPackages" value="true"/>
      <property name="trimStrings" value="true"/>
    </javaModelGenerator>
    <!--生成映射文件存放位置-->
    <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
      <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>
    <!--生成dao类存放位置-->
    <javaClientGenerator targetPackage="org.example.dao" type="XMLMAPPER" targetProject="src/main/java">
      <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>
    <!--生成对应表及类名-->
    <table tableName="user_info" domainObjectName="UserDo" enableCountByExample="false"
        enableUpdateByExample="false" enableDeleteByExample="false"
        enableSelectByExample="false" selectByExampleQueryId="false"
    ></table>
    <table tableName="user_password" domainObjectName="UserPasswordDO" enableCountByExample="false"
        enableUpdateByExample="false" enableDeleteByExample="false"
        enableSelectByExample="false" selectByExampleQueryId="false"
    ></table>
  </context>
</generatorConfiguration>

步骤7:根据步骤6中指定的位置,我们在org.example目录下新建一个dataobject的包,一个dao包。并测试是否能够成功生成相应的文件:

run——edit configurations——+maven——command line:mybatis-generator:generate——apply

然后我们运行这个新建的命令,可以看到resources/mapping下多了两个文件:

dataobject包与dao包下生成了如下文件:

手动删除两个Example文件。

步骤8:为了接入mybatis对应mysql的数据源,我们继续编写application.properties文件

 server.port = 8090
 mybatis.mapperLocations = classpath:mapping/*.xml

 spring.datasource.name = Spike
 spring.datasource.url = jdbc:mysql://127.0.0.1:3306/Spike
 spring.datasource.username = root
 spring.datasource.password = 0322

 #使用druid数据源
 spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
 spring.datasource.driverClassName = com.mysql.jdbc.Driver

步骤9:回到app.java

将@EnableAutoConfiguration注解改为@SpringBootApplication(scanBasePackages = "org.example"),作用是将app交给spring托管,并且指定为主启动类。

添加注解@MapperScan("org.example.dao"),把dao存放的地方设置在对应注解下面。

最后,写一个方法来测试我们的搭建工作是否完成,(事先在表格中添加一条数据)

 package org.example;
 import org.example.dao.UserDoMapper;
 import org.example.dataobject.UserDo;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;

 //SpringBoot会帮我们启动tomcat,并加载默认配置
 @SpringBootApplication(scanBasePackages = {"org.example"})

 //SpringMVC相关配置
 @RestController
 @MapperScan("org.example.dao")
 public class App {
   @Autowired
   private UserDoMapper userDoMapper;

   @RequestMapping("/")
   public String home(){
     UserDo userDo = userDoMapper.selectByPrimaryKey(1);
     if(userDo == null){
      return "用户对象不存在";
     }else{
       return userDo.getName();
     }
   }
   public static void main( String[] args ){
     //控制台输出
     System.out.println( "Hello World!" );
     SpringApplication.run(App.class,args);
   }
 }
app.java

打开http://localhost:8090/,我们可以看到页面上显示了我们添加的数据中name字段的内容。

三、用户模块开发

1.使用SpingMVC模式开发用户信息

步骤1:补全框架结构:

步骤2:service层的编写:

UserService接口:

package org.example.service;
import org.example.service.model.UserModel;
public interface UserService {
  UserModel getUserById(Integer id);
}

UserService实现类:

@Service
public class UserServiceImpl implements UserService {
  @Autowired
  private UserDoMapper userDoMapper;

  @Autowired
  private UserPasswordDOMapper userPasswordDOMapper;

  @Override
  public UserModel getUserById(Integer id) {
    UserDo userDo = userDoMapper.selectByPrimaryKey(id);
    if(userDo == null){
      return null;
    }
    //通过用户id获取对应的用户加密密码信息
    UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDo.getId());
    return convertFromDataObject(userDo,userPasswordDO);
  }

  public UserModel convertFromDataObject(UserDo userDo, UserPasswordDO userPasswordDO) {
    if(userDo == null){
      return null;
    }
    UserModel userModel = new UserModel();
    BeanUtils.copyProperties(userDo,userModel);
    if(userPasswordDO != null){
      userModel.setEncriptPassword(userPasswordDO.getEncriptPassword());
    }
    return userModel;
  }
}

UserModel类:存放数据库的所有对应字段与getters&setters,用于service层与数据库数据的解耦,使service层无法直接接触数据库

1 package org.example.service.model;
 2
 3 public class UserModel {
 4   private Integer id;
 5   private String name;
 6   private Byte gender;
 7   private Integer age;
 8   private String telephone;
 9   private String registerMode;
10   private String thirdPartyId;
11   private String encriptPassword;
12
13   public Integer getId() {
14     return id;
15   }
16
17   public void setId(Integer id) {
18     this.id = id;
19   }
20
21   public String getName() {
22     return name;
23   }
24
25   public void setName(String name) {
26     this.name = name;
27   }
28
29   public Byte getGender() {
30     return gender;
31   }
32
33   public void setGender(Byte gender) {
34     this.gender = gender;
35   }
36
37   public Integer getAge() {
38     return age;
39   }
40
41   public void setAge(Integer age) {
42     this.age = age;
43   }
44
45   public String getTelephone() {
46     return telephone;
47   }
48
49   public void setTelephone(String telephone) {
50     this.telephone = telephone;
51   }
52
53   public String getRegisterMode() {
54     return registerMode;
55   }
56
57   public void setRegisterMode(String registerMode) {
58     this.registerMode = registerMode;
59   }
60
61   public String getThirdPartyId() {
62     return thirdPartyId;
63   }
64
65   public void setThirdPartyId(String thirdPartyId) {
66     this.thirdPartyId = thirdPartyId;
67   }
68
69   public String getEncriptPassword() {
70     return encriptPassword;
71   }
72
73   public void setEncriptPassword(String encriptPassword) {
74     this.encriptPassword = encriptPassword;
75   }
76 }

步骤3:修改UserPasswordDOMapper.xml,添加一个selectByUserId操作的配置

<select id="selectByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
  select
  <include refid="Base_Column_List" />
  from user_password
  where user_id = #{userId,jdbcType=INTEGER}
 </select>

同步修改UserPasswordDOMapper.java,添加一行代码:

UserPasswordDO selectByUserId(Integer userId);

步骤4:编写Controller包中的UserController.java

@Controller("user")
@RequestMapping("/user")
public class UserController {
  @Autowired
  private UserService userService;
  @RequestMapping("/get")
  @ResponseBody
  public UserModel getUser(@RequestParam(name="id") Integer id) {
    //调用service服务获取对应id的用户对象并返回给前端
    UserModel userModel = userService.getUserById(id);
    return userModel;
  }
}

运行后,访问http://localhost:8090/user/get?id=1(需要事先添加好一条完整的数据),可以看到页面上输出了这条数据的完整信息。

步骤5:发现问题:在UserController中,我们把userModel模型直接返回给前端,导致密码直接输出在页面中,这是非常不专业的。

因此,我们在controller层(包)中需要新建一个模型对象。在controller层中新建一个viewobject包,并在其中写一个viewobject类,里面只写需要展示在前端的字段与getters&setters。

1 package org.example.controller.viewobject;
 2
 3 public class UserVO {
 4   //只写前端用户所需要的信息
 5   private Integer id;
 6   private String name;
 7   private Byte gender;
 8   private Integer age;
 9   private String telephone;
10
11   public Integer getId() {
12     return id;
13   }
14
15   public void setId(Integer id) {
16     this.id = id;
17   }
18
19   public String getName() {
20     return name;
21   }
22
23   public void setName(String name) {
24     this.name = name;
25   }
26
27   public Byte getGender() {
28     return gender;
29   }
30
31   public void setGender(Byte gender) {
32     this.gender = gender;
33   }
34
35   public Integer getAge() {
36     return age;
37   }
38
39   public void setAge(Integer age) {
40     this.age = age;
41   }
42
43   public String getTelephone() {
44     return telephone;
45   }
46
47   public void setTelephone(String telephone) {
48     this.telephone = telephone;
49   }
50 }

同时,我们修改UserController类,将UserModel转化为viewobject后,再返回给前端。

@Controller("user")
@RequestMapping("/user")
public class UserController {
  @Autowired
  private UserService userService;
  @RequestMapping("/get")
  @ResponseBody
  public UserVO getUser(@RequestParam(name="id") Integer id) {
    //调用service服务获取对应id的用户对象并返回给前端
    UserModel userModel = userService.getUserById(id);
    //将核心领域模型对象转化为可供UI使用的viewobject
    return convertFromModel(userModel);
  }
  private UserVO convertFromModel(UserModel userModel){
    if(userModel == null){
      return null;
    }
    UserVO userVO = new UserVO();
    BeanUtils.copyProperties(userModel,userVO);
    return userVO;
  }
}

这一步中,我们做了一个完整的从数据库中读取数据,展示在前端页面上的操作。

controller层——>service层——>dao层

dataobject层负责数据存储到service的传输,并且在用户的service的服务中组装了对应的核心领域模型。

controller层做了到用户viewobject之间的传递,保证密码等信息不会输出到前端。

2.定义通用的返回对象

步骤1:自主管理前端页面的返回——返回正确信息

org.example包下创建一个response包,在其中创建一个CommonReturnType.java文件。

在该文件中,设置两个属性:status,data,并生成对应的getters&setters。然后写两个构造方法,包含了两个属性的设置。

 package org.example.response;

 public class CommonReturnType {
   //表名对应请求的返回处理结果,success/fail
   private String status;
   //若status返回success,则data内返回前端需要的json数据
   //若status返回success,则data内使用通用的错误码格式
   private Object data;

   //定义一个通用的创建方法
   public static CommonReturnType create(Object result){
     return CommonReturnType.create(result,"success");
   }

   public static CommonReturnType create(Object result,String status){
     CommonReturnType type = new CommonReturnType();
     type.setStatus(status);
     type.setData(result);
     return type;
   }
   public String getStatus() {
     return status;
   }

   public void setStatus(String status) {
     this.status = status;
   }
   public Object getData() {
     return data;
   }
   public void setData(Object data) {
     this.data = data;
   }
 }

修改我们的UserController.java,将返回值改为CommonReturnType,由CommonReturnType调用create方法来引用UserVO中的信息。以下代码为需要修改的部分:

public CommonReturnType getUser(@RequestParam(name="id") Integer id) {
    //调用service服务获取对应id的用户对象并返回给前端
    UserModel userModel = userService.getUserById(id);
    //将核心领域模型对象转化为可供UI使用的viewobject
    UserVO userVO = convertFromModel(userModel);
    //返回通用对象
    return CommonReturnType.create(userVO);
  }

运行后,我们仍然访问http://localhost:8090/user/get?id=1,可以看到页面上输出了:

步骤2:自主管理前端页面的返回——返回错误信息

org.example包下创建一个error包,在其中创建一个CommonError接口,写3个方法:获取错误码,获取错误信息,设置错误信息

 public interface CommonError {
   public int getErrCode();
   public String getErrMsg();
   public CommonError setErrMsg(String errMsg);
 }

error包下写一个枚举类型的EmBusinessError,实现CommonError接口。

package org.example.error;

public enum EmBusinessError implements CommonError{
  //通用错误类型10001
  PARAMETER_VALIDATION_ERROR(10001,"参数不合法"),
  //未知错误10002
  UNKNOWN_ERROR(10002,"未知错误"),

  //20000开头相关为用户信息相关错误定义
  USER_NOT_EXIST(20001,"用户不存在"),
  ;

  private EmBusinessError(int errCode,String errMsg){
    this.errCode = errCode;
    this.errMsg = errMsg;
  }

  private int errCode;
  private String errMsg;

  @Override
  public int getErrCode() {
    return this.errCode;
  }

  @Override
  public String getErrMsg() {
    return this.errMsg;
  }

  @Override
  public CommonError setErrMsg(String errMsg) {
    this.errMsg = errMsg;
    return this;
  }
}

error包下写一个BusinessException,实现CommonError接口,并继承Exception类。

public class BusinessException extends Exception implements CommonError{
  private CommonError commonError;

  //直接接收EmBusinessError的传参用于构造业务异常
  public BusinessException(CommonError commonError) {
    super();
    this.commonError = commonError;
  }

  public BusinessException(CommonError commonError,String errMsg) {
    super();
    this.commonError = commonError;
    this.commonError.setErrMsg(errMsg);
  }

  @Override
  public int getErrCode() {
    return this.commonError.getErrCode();
  }

  @Override
  public String getErrMsg() {
    return this.commonError.getErrMsg();
  }

  @Override
  public CommonError setErrMsg(String errMsg) {
    this.commonError.setErrMsg(errMsg);
    return this;
  }
}

UserController中添加如下代码:

   //若获取的对应用户信息不存在
     if(userModel==null){
       throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
     }

步骤3:异常处理

在controller目录下单独写一个BaseController类,定义exceptionhandler解决未被controller层吸收的exception。

import java.util.Map;

public class BaseController {
  //定义exceptionhandler解决未被controller层吸收的exception
  @ExceptionHandler(Exception.class)
  @ResponseStatus(HttpStatus.OK)
  @ResponseBody
  public Object handlerException(HttpServletRequest request, Exception ex){
    Map<String,Object> responseData = new HashMap<>();
    if(ex instanceof BusinessException){
      BusinessException businessException = (BusinessException)ex;
      responseData.put("errCode",businessException.getErrCode());
      responseData.put("errMsg",businessException.getErrMsg());
    }else{
      responseData.put("errCode", EmBusinessError.UNKNOWN_ERROR.getErrCode());
      responseData.put("errMsg",EmBusinessError.UNKNOWN_ERROR.getErrMsg());

    }
    return CommonReturnType.create(responseData,"fail");
  }
}

然后,UserController类需要继承BaseController类。

运行后,我们访问http://localhost:8090/user/get?id=2,(id=2的数据是不存在的),可以看到页面为:

为了程序的健壮性,我们在BaseController中添加了一个unknown error。我们可以手动地来测试一下这段代码是否起了作用:

修改UserController部分代码如下:

    if(userModel==null){
       userModel.setEncriptPassword("123");
       //throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
     }

运行后,我们再次访问http://localhost:8090/user/get?id=2,可以看到页面为:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Springboot项目监听器失效问题解决

    1.使用springboot项目,现在有个需求是在添加或者修改某个菜单后,菜单会影响角色,角色影响用户.所有受影响的用户在要退出重新登录. 自己实现的思路是这样的:写一个监听器,在收到某个特定的请求后,监听当前所有的用户,如果是受影响的用户,就销毁session,让重新登录. 有了思路后,刚开始上网搜的是怎么在spring boot中添加监听:网上大部分的思路都一样:使用@ServletComponentScan和一个实现了HttpSessionListener的方法就可以了.但是自己按照这个配

  • 超个性修改SpringBoot项目的启动banner的方法

    如果我们使用过SpringBoot,那么就会对下面的图案不陌生.Springboot 启动的同时会打印下面的图案,并带有版本号. 查看SpringBoot官方文档可以找到关于 banner 的描述 The banner that is printed on start up can be changed by adding a banner.txt file to your classpath or by setting the spring.banner.location property t

  • SpringBoot项目application.yml文件数据库配置密码加密的方法

    在Spring boot开发中,需要在application.yml文件里配置数据库的连接信息,或者在启动时传入数据库密码,如果不加密,传明文,数据库就直接暴露了,相当于"裸奔"了,因此需要进行加密处理才行. 使用@SpringBootApplication注解启动的项目,只需增加maven依赖 我们对信息加解密是使用这个jar包的: 编写加解密测试类: package cn.linjk.ehome; import org.jasypt.encryption.pbe.StandardP

  • VsCode搭建Spring Boot项目并进行创建、运行、调试

    源码地址:https://github.com/YANGKANG01/Spring-Boot-Demo 安装扩展 安装如下两个主要扩展即可,这两个扩展已关联java项目开发主要使用的maven.springboot等所需要的扩展. 开始步骤: 在 Visual Studio Code 中打开扩展视图(Ctrl+Shift+X). 输入"java"搜索商店扩展插件. 找到并安装Java Extension Pack (Java 扩展包),如果你已经安装了Language Support

  • Springboot项目javax.validation使用方法详解

    javax.validation 是基于JSR-303标准开发出来的,使用注解方式实现,及其方便,但是这只是一个接口,没有具体实现. Hibernate-Validator是一个hibernate独立的包,可以直接引用,他实现了javax.validation同时有做了扩展,比较强大.SpringBoot在内部集成了hibernate-validation,可以直接使用. 常用注解: 代码 说明 @Null 被注解的元素必须为null @NotNull 被注解的元素必须不为null @Asser

  • 如何运行SpringBoot项目的方法

    最近在Ecplise上面写了一个简单的Spring Boot的测试项目,Spring Boot里面是有主函数的: 我们知道的是在Ecplise上面找到这个主函数然后run as->java Application 就可以了 但是总不能一直不脱离Ecplise,总要出来自己单练的 第一步:我就新建的一个文件夹boottest,然后右键导出整个工程: 导出的是jar包,然后我们看网上介绍的SpringBoot启动的方法,就兴致勃勃的去启动SpringBoot 第二步:将导出的jar包解压到我刚才创建

  • Spring Boot 项目设置网站图标的方法

    正常情况下,每个网站都会有一个对应的网站图标(Favicon),在浏览器访问网站时,对应的浏览器标签上会出现对应的图标.如下图百度的图标: 对此Spring Boot项目也提供了支持,但不同版本有所区别,在最新版本中的使用,网络上大多数文章已经失效,本篇文章带大家看一下Spring Boot 2.x版本中的使用情况. Spring Boot不同版本对Favicon的支持 在早些版本中Spring Boot对Favicon进行了默认支持,并且通过如下配置进行关闭操作: spring.mvc.fav

  • SpringBoot项目中处理返回json的null值(springboot项目为例)

    在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将null值转换为空字符串? 以SpringBoot项目为例,SSM同理. 1.新建配置类(JsonConfig.java) import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.f

  • 基于SpringBoot构建电商秒杀项目代码实例

    一.项目功能概述 电商秒杀需要完成的3个功能: 1.展示一个商品列表页面,我们可以从中看到可秒杀的商品列表 2.点击进入商品详情页,获取该商品的详细信息 3.秒杀时间开始后,点击进入下单确认页面,并支付成功 二.基于SpringBoot进行项目环境搭建 步骤1:创建一个maven工程,使用quickStart骨架. 步骤2:在pom.xml导入SpringBoot相关依赖. <?xml version="1.0" encoding="UTF-8"?> &

  • 基于vue3.0.1beta搭建仿京东的电商H5项目

    前言 就在前段时间,vue官方发布了3.0.0-beta.1 版本,趁着五一假期有时间,就把之前的一个电商商城的项目,用最新的Composition API拿来改造一下! GitHub地址请访问:https://github.com/GitHubGanKai/vue3-jd-h5 项目介绍 vue-jd-h5是一个电商H5页面前端项目,基于Vue 3.0.0-beta.1 + Vant 实现,主要包括首页.分类页面.我的页面.购物车等. 本地线下代码vue2.6在分支demo中,使用mockjs

  • 基于Vue实现电商SKU组合算法问题

    前段时间,公司要做"添加商品"业务模块,这也算是电商业务里面的一个难点了. 令我印象最深的不是什么"组合商品"."关联商品"."关联单品",而是商品SKU的组合问题. 这个问题特别有意思,当时虽然大体上组合成功,总是有些小bug解决不了,然后手上又有别的任务就没仔细研究它. 后来过了一个月,空闲下来专门研究了下,终于把问题解决,有必要记录下这次体验. 先看下在业务中的效果(tips: 如看不清可放大浏览器) 这个相对来说比较麻

  • Python探索之爬取电商售卖信息代码示例

    网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 下面有一个示例代码,分享给大家: #! /usr/bin/env python # encoding = 'utf-8'# Filename: spider_58center_sth.py from bs4 import BeautifulSoup import time import requests url_58 = 'http://nj.58.c

  • 解密Redis助力双11背后电商秒杀系统(推荐)

    背景 秒杀活动是绝大部分电商选择的低价促销,推广品牌的方式.既可以给平台带来用户量,还可以提高平台知名度.一个好的秒杀系统,可以提高平台系统的稳定性和公平性,获得更好的用户体验,提升平台的口碑,从而提升秒杀活动的最大价值. 本文讨论云数据库Redis版缓存设计高并发的秒杀系统. 秒杀的特征 秒杀活动对稀少或特价的商品进行定时定量售卖,吸引成大量的消费者进行抢购,但又只有少部分消费者可以下单成功.因此,秒杀活动将在一定时间内产生比平时大几十倍倍,上百倍的页面访问流量和下单请求流量. 秒杀活动可以分

  • iOS开发仿电商类APP首页实例

    现在淘宝,京东应用很广泛,今天就效仿做一个类似电商APP首页的实例. 一.Gif效果图: 二.UI布局: 看下图的层级关系,除去最下方的TabBar,首页其余部分全是用UICollectionView实现:其分两大部分,实现三种功能.上方是父UICollectionView的headerView,在此headerView中添加了两个UICollectionView,分别实现图片无限轮播器和一个横向滑动的功能菜单按钮.然后下面就是父UICollectionView的cell,上下滑动展示商品内容.

  • 微信小程序电商常用倒计时实现实例

    微信小程序电商常用倒计时实现实例 wxml文件放个text <text>second: {{second}} micro second:{{micro_second}}</text> 在js文件中调用 function countdown(that) { var second = that.data.second if (second == 0) { // console.log("Time Out..."); that.setData({ second: &q

  • springboot配置允许跨域访问代码实例

    这篇文章主要介绍了springboot配置允许跨域访问代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 因springboot框架通常用于前后端分离项目,因此需配置后台允许跨域访问(具体看注释),配置类如下,将该类加入工程中即可. import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configu

  • 基于java web获取网页访问次数代码实例

    这篇文章主要介绍了基于java web获取网页访问次数代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 ServletContext context = request.getServletContext(); /** * 从ServletContext中获取计数器对象 */ Integer count = (Integer) context.getAttribute("counter"); /** * 如果为空,则在Servl

  • 基于js实现抽红包并分配代码实例

    这篇文章主要介绍了基于js实现抽红包并分配代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 将 50000元随机分给10个人,其中3个人必须分到百位数,4个人分到千位数,3个人分到万位数,每个人所得金额 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name=&

随机推荐