【Java】Spring boot快速上手(三)前后端分离实现小程序登录(接口篇)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【Java】Spring boot快速上手(三)前后端分离实现小程序登录(接口篇)

前言

例如:


一、新建spring项目

创建springboot项目

安装一些依赖文件

等待安装

二、建立设计数据库

由于我的本地没有mysql服务,就用服务器ip作为演示了,大家可以下载个phpstudy配置完成后运行mysql即可

新建User表

创建字段

CREATE TABLE `qianxun`.`User` ( `id` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(20) NOT NULL , `password` VARCHAR(20) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

创建后插入账号密码


三、配置环境及编写接口

spring.application.name=demo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.name=user
spring.datasource.url=jdbc:mysql://localhost:3306/qianxun?serverTimezone=UTC
spring.datasource.username=qianxun
spring.datasource.password=123123
server.port=8080
mybatis.mapper-locations=classpath:mappers/*xml
mybatis.type-aliases-package=com.example.demo.mybatis.entity

配置后运行测试,不报错就说明数据库连接上了

配置mybatis框架(扫描mapper文件)

代码

package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

新建3个package

创建实体类,在entity文件夹下新建User.java完成字段映射,如下所示

上一篇说到构造函数使用 alt+ins 弹出快捷键

完成构造函数的编辑,这里可以用刚刚的lomb函数省略

所以(请注意需要与数据库字段匹配)

User.java

package com.example.demo.entity;
import lombok.Data;
@Data
public class User {
    private int id;
    private String username;
    private String password;
}

在mapper文件夹下新建UserMapper.java

package com.example.demo.mapper;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
    @Select("select id from User where username = #{username}")
    String findById(String username);
}

在controller文件夹下新建UserController.java

package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;
//    引用spring容器资源
    @GetMapping("/{username}")
    public  String findById(@PathVariable("username") String username) {
        return userMapper.findById(username);
    }
}

用户通过访问控制器的api路径,例如

http://localhost:8080/user/123

通过get查询username是否存在,存在返回id值

但是我们登录是需要两个参数账户和密码

所以需要更改参数接收

UserController.java部分

@RequestMapping(value="/login")
public String logins(@RequestParam("username") String username,
@RequestParam("password") String password) {
    System.out.println("username is:" + username);
    System.out.println("password is:" + password);
}

访问

http://localhost:8080/user/login?username=123&password=123

通过接口完成返回

UserController.java部分

@RequestMapping(value="/login")
public String logins(@RequestParam("username") String username,
@RequestParam("password") String password) {
    System.out.println("username is:" + username);
    System.out.println("password is:" + password);
    String id=userMapper.findById(username,password);
    System.out.println(id);
    if (id!=null){
        return "{\"code\": 200, \"msg\": \"登陆成功\", \"data\": \"登陆成功\"}";
   }else{
        return "{\"code\": 202, \"msg\": \"登陆失败\", \"data\": \"登陆失败\"}";
    }
}

因为data里面需要放查到的数据,所以我们还得改代码,把查到的数据通过之前构造的映射来返回

所以

@RequestMapping(value="/login")
public String logins(@RequestParam("username") String username,
@RequestParam("password") String password) {
    System.out.println("username is:" + username);
    System.out.println("password is:" + password);
    String id=userMapper.findById(username,password);
    System.out.println(id);
    if (id!=null){
        List<User> result=userMapper.login(username,password);
        return "{\"code\": 200, \"msg\": \"登陆成功\", \"data\": "+result+"}";
   }else{
        return "{\"code\": 202, \"msg\": \"登陆失败\", \"data\": \"\"}";
    }
}

完整的代码

UserController.java

package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
//将下面的返回类型都改为json
@RequestMapping("/user")
public class UserController {
    @Resource
    UserMapper userMapper;
//    引用spring容器资源
@RequestMapping(value="/login")
public String logins(@RequestParam("username") String username,
@RequestParam("password") String password) {
    System.out.println("username is:" + username);
    System.out.println("password is:" + password);
    String id=userMapper.findById(username,password);
    System.out.println(id);
    if (id!=null){
        List<User> result=userMapper.login(username,password);
        return "{\"code\": 200, \"msg\": \"登陆成功\", \"data\": \""+result+"\"}";
   }else{
        return "{\"code\": 202, \"msg\": \"登陆失败\", \"data\": \"\"}";
    }
}
//
}

User.java

package com.example.demo.entity;
import lombok.Data;
@Data
public class User {
    private int id;
    private String username;
    private String password;
}

UserMapper.java

package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
    @Select("select id from User where username =  #{username} and password =  #{password}")
    String findById(@Param(value = "username")String username,@Param(value = "password")String password);
    @Select("select * from User where username =  #{username} and password =  #{password}")
    List<User> login(@Param(value = "username")String username,@Param(value = "password")String password);
}


四、4个包的说明

mapper- - - - - - -增删查改

controler- - - - - -控制器(提供对外访问api数据)

entity- - - - - - - - 实体类(定义数据类型且与数据库一一对应)

五、部分注解说明

@RestController - - - - - 将下方返回类型转换为json
@RequestMapping()- - - - - 接口、方法路径,使方法通过接口去访问
@Resource- - - - - - - - - 资源引用

六、小程序实现api登录

新建小程序项目,这里不多少,不会的可以看我的文章

login.wxml

<form class="login-form">
  <view class="input-group {{userid_focus ? 'active' : ''}}">
    <text class="input-label">帐号</text>
    <input type="number" cursor-spacing="30" id="userid" maxlength="7" placeholder="请输入账号" bindinput="getusername"/>
  <view>
  <view class="input-group {{passwd_focus ? 'active' : ''}}">
    <text class="input-label">密码</text>
    <input password="true" cursor-spacing="30" id="passwd" placeholder="输入密码"bindinput="getpw"/>
  <view>
<button type="primary" bindtap="login">登录<button >
</form>

login.wss

.login-form {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
}
.input-group {
  display: flex;
  align-items: center;
  padding: 25rpx 10rpx;
  margin: 40rpx 3%;
  background: #fff;
  border-radius: 5px;
  border: 2px solid #f4f4f4;
  transition: all .25s ease-in-out;
}
.input-group.active {
  border: 2px solid #7acfa6;
}
.input-label {
  color: #888;
  font-size: 13pt;
  height: 25rpx;
  line-height: 25rpx;
  padding: 0 25rpx;
  border-right: 1px solid #d8d8d8; 
}
.input-group input,
.input-group picker {
  flex: 1;
  font-size: 13pt;
  min-height: 52rpx;
  height: 52rpx;
  line-height: 52rpx;
  padding: 0 25rpx;
}

login.js

// pages/login/login.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
username:'',
password:''
  },
  getpw(e){
    console.log(e.detail.value)
    this.setData({
      password:e.detail.value
    })
  },
  getusername(e){
    console.log(e.detail.value)
    this.setData({
      username:e.detail.value
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
  },
login:function(){
  let that=this;
console.log("登录");
wx.request({
  url: 'http://192.168.1.126:8080/user/login',
  data:{
    username:that.data.username,
    password:that.data.password,
  },
  header: {
    'content-type': 'application/json' // 默认值
    },
    success (res) {
    console.log(res.data)
    if (res.data.code==200) {
      wx.showToast({
        title: '登陆成功',
      })
    } else {
      wx.showToast({
        title: '登陆失败',
        icon:'none'
      })
    }
    }
})
},
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
  }
})

五、关于传参的七种

1、直接把请求参数写在Controller相应的方法的形参中,此场景适用于请求参数较少的情况

/**
    * 1.
    直接把请求参数写在
    Controller
    相应的方法的形参中
    * @param username
    * @param password
    * @return
  */
  @RequestMapping("/addUser1")
  public String addUser1(String username,String password) {
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
    return "success";
  }

此处的RequestMapping中没有限定请求方式,那么get和post的请求方式都是可以接收的。get的请求方式我们可以直接在浏览器中输入地址,

  端口可以自行在application.properties中配置,然后使用postman工具进行测试

2、封装一个bean直接来接收,我们这里使用上一个案例中封装好的User类来进行接收,同时适用

  get、post方法。

UserController中的代码如下:
  @RequestMapping("/addUser2")
  public String addUser2(User user) {
    System.out.println("id is:"+user.getId());
    System.out.println("username is:"+user.getUsername());
    System.out.println("password is:"+user.getPassword());
    return "success";
  }

此时我们可以继续使用postman进行测试,注意这里传入的参数名要和User里面的属性名称一致(首字母之外的大小写保持一致,已测),否则无法识别接收,则相应的值会为null

3、通过原生的HttpServletRequest接收,同时适用get、post方法。

@RequestMapping("/addUser3")
  public String addUser3(HttpServletRequest request) {
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
    return "success";
  }

测试方法同上,这里就不再演示。

4、通过@PathVariable获取rest风格请求路径中的参数

@RequestMapping(value="/addUser4/{username}/{password}")
  public String addUser4(@PathVariable String username, @PathVariable String password) {
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
    return "success";
  }

此时测试访问路径应该是rest风格的路径,如

    http://127.0.0.1:8883/addUser4/xiadewang/123456

    自动将URL中模板变量{username}和{password}绑定到通过@PathVariable注解的同名参数上

    注意这里的参数个数一定要保持相同,否则会报404的错误。

5、使用@ModelAttribute注解请求参数,同时适用get,post

@RequestMapping(value="/addUser5")
  public String addUser5(@ModelAttribute("user") User user) {
    System.out.println("id is:"+user.getId());
    System.out.println("username is:"+user.getUsername());
    System.out.println("password is:"+user.getPassword());
    return "success";
  }

6、使用注解@RequestParam绑定请求参数到方法形参,同时适用get、post方法。

@RequestMapping(value="/addUser6")
  public String addUser6(@RequestParam("username") String username,
    @RequestParam("password") String password) {
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
    return "success";
  }

注意:当请求参数username或者password不存在时会有异常发生,可以通过设置属性required=false解决

  例如:

@RequestParam(value="username", required=false)

7、使用注解@RequestBody绑定请求参数到方法形参,只适用post方法。

@RequestMapping(value="/addUser7")
    public String addUser7(@RequestBody User user) {
    System.out.println("id is:"+user.getId());
    System.out.println("username is:"+user.getUsername());
    System.out.println("password is:"+user.getPassword());
    return "success";
  }

关于最后这个@RequestBody要重点讲解下,此时前端发送请求不能使用get方式,需要使用post方式,还有请求传递的参数需要是json字符串,这里重点要设置的是Content-Type,要将其设置为application/json。我们此时使用postman测试如下

这里如果不设置content-type的话,会报如下错误

小结

RequestBody和RequestParam同时使用的场景,代码如下

@RequestMapping(value="/addUser8")
public String addUser8(@RequestBody User user,@RequestParam("token") String token) {
  System.out.println("token is:"+token);
  System.out.println("id is:"+user.getId());
  System.out.println("username is:"+user.getUsername());
  System.out.println("password is:"+user.getPassword());
  return "success";
}

总结

以上就是今天要讲的内容,博主也在不断学习springboot,对于文中有些说不清楚的,请参考文章顶部视频,学习是个积累的过程,不可能这篇文章就能全部搞懂,后面一起努力吧!!!

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
存储 Java 编译器
Java中的抽象类与接口,在阿里工作5年了
Java中的抽象类与接口,在阿里工作5年了
|
6天前
|
Java 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口(下)
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口
44 0
|
6天前
|
Java 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口(上)
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口
47 0
|
6天前
|
Java 开发者
Java一分钟之-Lambda表达式与函数式接口
【5月更文挑战第12天】Java 8引入的Lambda表达式简化了函数式编程,与函数式接口结合,实现了代码高效编写。本文介绍了Lambda的基本语法,如参数列表、箭头符号和函数体,并展示了如何使用Lambda实现`Runnable`接口。函数式接口仅有一个抽象方法,可与Lambda搭配使用。`@FunctionalInterface`注解用于确保接口具有单一抽象方法。文章还讨论了常见的问题和易错点,如非函数式接口、类型冲突以及Lambda表达式的局部变量可见性,并提供了避免这些问题的策略。通过理解Lambda和函数式接口,开发者能提高代码可读性和效率。
44 4
|
1天前
|
安全 Java 编译器
Java一分钟之——泛型方法与泛型接口
【5月更文挑战第20天】Java泛型提供编译时类型安全检查,提升代码重用和灵活性。本文探讨泛型方法和接口的核心概念、常见问题和避免策略。泛型方法允许处理多种数据类型,而泛型接口需在实现时指定具体类型。注意类型擦除、误用原始类型和泛型边界的理解。通过明确指定类型参数、利用通配符和理解类型擦除来避免问题。泛型接口要精确指定类型参数,适度约束,利用默认方法。示例代码展示了泛型方法和接口的使用。
26 1
Java一分钟之——泛型方法与泛型接口
|
2天前
|
并行计算 Java API
Java 8中的接口默认方法和静态方法以及并行数组
【5月更文挑战第19天】Java 8引入了许多新特性,其中包括接口的默认方法和静态方法,以及并行数组的能力。这些特性增强了Java的面向对象编程模型和数组处理能力。让我们深入了解它们的概念和实践。
20 2
|
3天前
|
存储 Java
Java一分钟之-高级集合框架:Queue与Deque接口
【5月更文挑战第18天】本文探讨Java集合框架中的`Queue`和`Deque`接口,两者都是元素序列的数据结构。`Queue`遵循FIFO原则,主要操作有`add/remove/element/peek`,空队列操作会抛出`NoSuchElementException`。`Deque`扩展`Queue`,支持首尾插入删除,同样需注意空`Deque`操作。理解并正确使用这两个接口,结合具体需求选择合适数据结构,能提升代码效率和可维护性。
29 4
|
4天前
|
前端开发 JavaScript Java
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
|
4天前
|
移动开发 监控 供应链
JAVA智慧工厂制造生产管理MES系统,全套源码,多端展示(app、小程序、H5、台后管理端)
一开始接触MES系统,很多人会和博主一样,对MES细节的应用不了解,这样很正常,因为MES系统相对于其他系统来讲应用比较多!
16 1
JAVA智慧工厂制造生产管理MES系统,全套源码,多端展示(app、小程序、H5、台后管理端)
|
5天前
|
Java
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数

热门文章

最新文章