支付项目:6、用户模块(1)

相关约定

  • Content-Type:application/json
  • 开发顺序:Dao --> Service --> Controller
  • 单元测试:Service层
  • MyBatis打印SQL语句

Service完成注册功能

IUserImpl.java:

{

    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(User user) {
        //username不能重复
        int countByusername = userMapper.countByUsername(user.getUsername());
        if(countByusername > 0) {
            throw new RuntimeException("该username已注册");
        }
        //email不能重复
        int countByEmail = userMapper.countByEmail(user.getEmail());
        if(countByEmail > 0) {
            throw new RuntimeException("该email已注册");
        }
        //MD5加密密码(spring自带了)
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8)););
        //写入数据库
        int resultCount = userMapper.insertSelective(user);
        if(resultCount == 0) {
            //说明没有写进去
            throw new RuntimeException("注册失败");
        }
    }
}

countByUsername、countByEmail:

<select id="countByUsername" parameterType="java.lang.String" resultType="java.lang.Integer">
  select count(1)
  from mall_user
  where username = #{username,jdbcType=VARCHAR}
</select>
<select id="countByEmail" parameterType="java.lang.String" resultType="java.lang.Integer">
  select count(1)
  from mall_user
  where email = #{email,jdbcType=VARCHAR}
</select>

service注册功能单测

package com.xiaoxin.mall.service.impl;

import com.xiaoxin.mall.MallApplicationTests;
import com.xiaoxin.mall.enums.RoleEnum;
import com.xiaoxin.mall.pojo.User;
import com.xiaoxin.mall.service.IUserService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.Assert.*;

//在单测上面加Transactional注解就是起回滚的作用,因为是测试嘛,不需要真的往数据库写值
@Transactional
public class IUserServiceImplTest extends MallApplicationTests {

    @Autowired
    private IUserService userService;

    @Test
    public void register() {
        User user = new User("xiaoxin", "915013255@qq.com", "123456", RoleEnum.ADMIN.getRole());
        userService.register(user);
    }
}

RoleEnum.java

package com.xiaoxin.mall.enums;

import lombok.Getter;

@Getter
public enum RoleEnum {

    ADMIN(0),

    CUSTOMER(1),

    ;

    Integer role;

    RoleEnum(Integer role) {
        this.role = role;
    }
}

MyBatis打印SQL语句

1、在application.yml中配置mybatis的log-impl属性:

mybatis:
  configuration:
    map-underscore-to-camel-case: true
    # 控制台日志配置
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mappers/*.xml

这样就发现,在控制台打印出来了sql语句:
在这里插入图片描述

controller接收参数

package com.xiaoxin.mall.controller;

import com.xiaoxin.mall.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @PostMapping("/register")
    public void register(@RequestBody User user) {
        log.info("username={}", user.getUsername());
    }
}

1、如果使用urlencoded方式传递参数,那么可以这样写

@PostMapping("/register")
public void register(User user) {
    log.info("username={}", user.getUsername());
}

或者这样:

@PostMapping("/register")
public void register(@RequestParam String username) {
    log.info("username={}", username);
}

2、如果使用json方式传递参数,那么user参数要使用@RequestBody注解

注意:@RestController 注解相当于@Controller和@ResponseBody注解的结合

Controller返回Json

1、创建一个新的类 ResponseVO

package com.xiaoxin.mall.service.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

@Data
@JsonInclude(value= JsonInclude.Include.NON_NULL)
public class ResponseVo<T> {

    private Integer status;

    private String msg;

    private T data;

    public ResponseVo(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    public static <T> ResponseVo<T> success(String msg) {
        return new ResponseVo<>(0, msg);
    }
}

@JsonInclude(value= JsonInclude.Include.NON_NULL)这个注解的作用是,在将类返回成JSON格式的数据时,忽略掉那些为null的成员变量。

2、测试

package com.xiaoxin.mall.controller;

import com.xiaoxin.mall.pojo.User;
import com.xiaoxin.mall.service.vo.ResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @PostMapping("/register")
    public ResponseVo register(@RequestBody User user) {
        log.info("username={}", user.getUsername());
        return ResponseVo.success("注册成功");
    }
}

在这里插入图片描述

错误状态码使用枚举

1、编写枚举类

package com.xiaoxin.mall.enums;

import lombok.Getter;

@Getter
public enum ResponseEnum {

    ERROR(-1, "服务端异常"),

    SUCCESS(0, "成功"),

    PASSWORD_ERROR(1, "密码错误"),

    USER_EXIST(2, "用户已存在"),

    NEED_LOGIN(10, "用户未登录,请先登录"),

    ;

    Integer code;

    String desc;

    ResponseEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}

2、在ResponseVo类中使用:

package com.xiaoxin.mall.service.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.xiaoxin.mall.enums.ResponseEnum;
import lombok.Data;

@Data
@JsonInclude(value= JsonInclude.Include.NON_NULL)
public class ResponseVo<T> {

    private Integer status;

    private String msg;

    private T data;

    public ResponseVo(Integer status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    public static <T> ResponseVo<T> success(String msg) {
        return new ResponseVo<>(ResponseEnum.SUCCESS.getCode(), msg);
    }

    public static <T> ResponseVo<T> success() {
        return new ResponseVo<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getDesc());
    }

    public static <T> ResponseVo<T> fail() {
        return new ResponseVo<>(ResponseEnum.PASSWORD_ERROR.getCode(), ResponseEnum.PASSWORD_ERROR.getDesc());
    }
}

表单验证

1、创建类UserForm,这个类中只有username、password和email属性,因为验证时只需要验证这三个属性:

package com.xiaoxin.mall.form;

import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data
public class UserForm {

    //@NotBlank  用于String  判断空格
    //@NotEmpty  用于集合
    //@NotNULL
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;

    @NotBlank(message = "邮箱不能为空")
    private String email;
}

@NotBlank注解的作用是,当该属性为空时会提示错误信息。

2、改写ResponseVo的error的方法:

public static <T> ResponseVo<T> error(ResponseEnum responseEnum) {
        return new ResponseVo<>(responseEnum.getCode(), responseEnum.getDesc());
    }

public static <T> ResponseVo<T> error(ResponseEnum responseEnum, String msg) {
    return new ResponseVo<>(responseEnum.getCode(), msg);
}

public static <T> ResponseVo<T> error(ResponseEnum responseEnum, BindingResult bindingResult) {
    return new ResponseVo<>(responseEnum.getCode(),
            bindingResult.getFieldError().getField() + " " +
                 bindingResult.getFieldError().getDefaultMessage());
}

3、在Controller中使用:

@PostMapping("/register")
public ResponseVo register(@Valid @RequestBody UserForm userForm,
                            BindingResult bindingResult) {
    if(bindingResult.hasErrors()) {
        log.info("注册提交的信息有误,{}",
                    bindingResult.getFieldError().getDefaultMessage());
        return ResponseVo.error(ResponseEnum.PARAM_ERROR, bindingResult);
    }
    log.info("username={}", userForm.getUsername());
    return ResponseVo.success();
}

4、使用postman进行验证:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值