Java小白成长记(创作笔记二)
目录
序言
思维导图
续
用户登录/注册
数据表
实体层
持久层
服务层
认证与授权
整合springsecurity
controller注册测试
controller登录测试
跨域解决
方法
Java小白成长记(创作笔记一)
Java小白成长记(创作笔记二)
序言
在一个充满阳光的早晨,一位对编程世界充满好奇的年轻人小小白,怀揣着梦想与激情,踏上了学习Java编程的征程。他/她深知,在这个信息化时代,编程技能的重要性不言而喻。然而,作为一个编程小白,他面临着无数未知与挑战。在这篇成长记中,我们将紧紧跟随小小白的脚步,见证他/她从Java小白成长为大佬的蜕变历程。接下来,让我们出发吧 ····👻👻
思维导图
首页,要开发一个Java项目,我们要事先搭建思维导图,这样我们可以更好地梳理出项目的结构,前期可以做到一目了然,分步骤去写好每一块内容,避免出现这块写一点,又跳到那块再写,反复横跳·····后期完成也可以进行更好地优化和迭代。简而言之,高效 高效 高效
这是此篇博客的思维导图,内容主要针对后端
讲解了此次项目的学习重点、项目功能、技术栈以及开发流程,接下来就让我们跟随小小白的视角进入开发流程的探索吧!
续
用户登录/注册
首先小小白在这里给大家推荐两个懒人的插件! 作为Java开发者,尤其是做业务开发的,免不了要写一大堆接口,也就是我们所说的 Controller API。身为一名合格的后端开发人员,我们不能直接把写完的接口抛给前端用(当然也可以💥💥)
言归正传,我们平时做接口测试的时候可能用的是Postman,但是为了不用来回切换跳转,我们可以用IDEA内置的插件:HTTP Client,在插件市场搜索 HTTP Client 安装即可,这还是 JetBrains 官方出品的
安装完成后,我们在Controller 中带有 @RequestMapping、@GetMapping
、@PostMapping
注解的HTTP接口前都会多一个小图标,类似这样
当我们点击的时候,选中第二个就会自动跳转
当跳转进来的时候,我们可以直接在给我们写的请求改,也可以通过上面的 + 发送各种不同的请求,这样就不用切换到Postman,提供了一点点迅捷🤪🤪
当我们发送Post请求的时候,如果参数太多,那么POJO to JSON就是帮助我们简化的,我们直接进行安装重启就行
然后直接在实体类中右键选中,直接Copy就不用自己手写参数多的地方
当然少的也可以直接Copy👻👻
数据表
首先基于登录/注册,我们先搭建一个数据库(mysql)表,用来存储账号和密码,由于在Java小白成长记(创作笔记一)当中已经简单介绍数据库的配置,这里就不进行说明了,可以点击目录(一)进行查看🫡🫡🫡(下面链接也行)。接下来直接进行操作:先点击右边仓库
Java小白成长记(创作笔记一)-CSDN博客
之后会出现一个写mysql语句的界面,可以将下面的代码复制运行
代码展示: use 自己数据库名;
# 选择数据库
use aurora;
# 登录/注册表
create table user(
id bigint(20) not null auto_increment,
username varchar(64) not null,
password varchar(64) not null,
primary key(id),
unique key uk_username(username)
)engine=innodb default charset=utf8mb4;
温馨提示:先"cmd"连接自己的数据库,可以看成长记(一)
实体层
在最外层包上右键New新建package,包名为entity
在新建的entity包上右键new一个Java Class类,类名为User(选Class)
这是User类代码:@Data是getter setter方法的注解,加了就不用再写getter/setter ; @TableName("user")是数据库表名 ;@TableId()是主键id自增长策略
package com.aurora.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @author aurora
* 注册/登录
*/
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
}
持久层
在最外层包上右键New新建package,包名为mapper,同上面类似(因为使用的MybatisPlus,所有不用再写xml文件)。然后在新建的mapper包上右键new一个Java Class类,接口名为UserMapper(注意选择Interface,这里是接口)
代码展示:继承一中集成了MybatisPlus方法 <实体类名>
package com.aurora.mapper;
import com.aurora.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
// 继承MybatisPlus的BaseMapper方法
public interface UserMapper extends BaseMapper<User>{
}
服务层
在最外层包上右键New新建package,包名为service,同上面类似。然后在新建的service包上右键new一个Java Class类,接口名为UserService(注意选择Interface,这里是以接口+继承方式实现的。目的:类很多时可以快速根据接口和接口实现类找出实现)
接口代码:
package com.aurora.service;
import com.aurora.common.Result; //Result是(一)中的封装响应类
import com.aurora.entity.User;
public interface UserService {
//注册
Result register(User user);
//注册
Result login(String username,String password);
}
然后在service包右键创建一个package包impl(接口实现类包),再在impl右键创建一个实现类(当然也可以在service包下直接写类,但是如果类很多的话建议以接口+接口实现类的方式实现)
实现类代码:提示(PasswordEncoder在下面,密码加密用的)
可以直接进行复制,改下"aurora"包名就行,也可以直接敲一遍,加深印象。自己敲的话在实现类中创建好类后会出爆出一根红线,直接继承接口的方法就行
package com.aurora.service.impl;
import com.aurora.common.Result;
import com.aurora.entity.User;
import com.aurora.exception.AppException;
import com.aurora.exception.AppExceptionCodeMsg;
import com.aurora.mapper.UserMapper;
import com.aurora.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
/**
* @author : aurora
*注册/登录验证
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
//注入springsecurity的密码加密
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Result register(User user) {
//检查用户是否存在 QueryWrapper(mybatisplus的一个方法)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",user.getUsername());
User existUser = userMapper.selectOne(queryWrapper);
if(existUser != null){
throw new AppException(AppExceptionCodeMsg.USERNAME_EXIST);
}
//加密密码
String encodePassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodePassword);
//保存用户
userMapper.insert(user);
return Result.success("注册成功",user);
}
@Override
public Result login(String username, String password) {
//查询用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
User user = userMapper.selectOne(queryWrapper);
//校验用户和密码
if(user == null || !passwordEncoder.matches(password,user.getPassword())){
throw new AppException(AppExceptionCodeMsg.INVALID_CODE);
}
return Result.success("登录成功",user);
}
}
PasswordEncoder类: springsecurity进行密码加密
这里的PasswordEncoder应该会报错,因为这还没添加依赖,可以先在这里将springsecurity的pom依赖先添加进去,就不会报错了
<!-- Spring Security依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
package com.aurora.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig{
// 密码加密
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
认证与授权
整合springsecurity
先添加pom依赖(上面添加了这里就不用添加)
<!-- Spring Security依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
当我们添加这段依赖后再访问一个接口,比如在controller中:然后启动springboot项目,再在浏览器输入http://localhost:8081/test (8081是设置的端口号) ,然后会让你输入账号和密码,比如下面
package com.aurora.controller;
import com.aurora.common.Result;
import com.aurora.exception.AppException;
import com.aurora.exception.AppExceptionCodeMsg;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
@RestController
public class TestController {
@GetMapping("/test")
public Result<String> test_01(String name){
if("ok".equals(name)){
return Result.success("Thanks OK!");
}
if("error".equals(name)){
throw new AppException(AppExceptionCodeMsg.USERNAME_NOT_EXIST);
}
if("1111".equals(name)){
throw new AppException(AppExceptionCodeMsg.INVALID_CODE);
}
return Result.success("default");
}
}
会弹出一个登录框,让输入账号和密码,账号是user,密码是控制台生成的,去复制填进去就可以访问到了,由于我们用了springsecurity,避免每次密码改变,直接在application.yml中配置一下账号和密码
application.yml
# 端口
server:
port: 8081
# DataSource Config
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/aurora?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: # 自己的密码
security:
user:
name: user # 因为我们用了密码加密,所有得填加密后的
password: $2a$10$F.WE3i3YXvXPLjZZJzq.CeACu26RP4WT5/ColdAfBKrZop4Ch9JF6 #加密后的111111
# 日志
logging:
level:
root: info
com.aurora: debug
# MybatisPlus
mybatis-plus:
mapper-locations: classpath*:/mapper/**Mapper.xml
现在应该就可以访问到了。
配置springsecurity白名单
白名单就是不需要进行接口验证,直接就可以发送请求到我们的controller接口当中
package com.aurora.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig{
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 配置白名单 /public/路径下的不需要验证
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated() // 其他所有请求都需要认证
)
// 禁用CSRF保护
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
}
现在我们再在之前的controller中添加一个/public/。@GetMapping("/public/test"),就不用在进行验证了,可以直接访问到,当我们注册/登录时,就可以直接发送请求到controller接口
如果需要访问之前的参数用"?"比如:http://localhost:8081/public/test?name=1111,可以返回不同的结果
controller注册测试
我们用上面的HTTP Client插件简单进行测试一下,代码:
package com.aurora.controller;
import com.aurora.common.Result;
import com.aurora.entity.User;
import com.aurora.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AuthController {
@Autowired
private UserService userService;
@PostMapping("/public/register")
public Result register(@RequestBody User user){ //@RequestBody 接收的实体类中数据
return userService.register(user);
}
@PostMapping("/public/login") //@RequestParam 接收两个参数
public Result login(@RequestParam String username, @RequestParam String password){
return userService.login(username,password);
}
}
测试注册:直接点击Post请求上的图标 然后输入json数据
检查数据库是否有信息添加:也可以在命令行看或者数据库工具
可以看到我们刚才注册的数据已经被添加到数据库了
controller登录测试
测试登录:点击 + 再点击框中的
再输入: 直接再上面改端口和URL就是了,不用重新输一遍
到这里,登录/注册功能就已经简单实现了
跨域解决
方法
解决跨域方式有好几种,这里就只给大家展示以配置方式进行解决跨域问题。下面这个链接中有五种解决跨域的方式,可以看了代码再仔细观摩学习一下😶🌫️😶🌫️
链接:SpringBoot解决跨域的5种方式_springboot跨域-CSDN博客
配置解决跨域代码:
package com.aurora.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 跨域配置
@Configuration
public class CoreConfig implements WebMvcConfigurer {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addExposedHeader("Authorization");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
.allowedMethods("GET","POST","DELETE","PUT")
.maxAge(3600);
}
}
温馨提示:大家这个就不用跟着敲了,直接把类名写成一样的复制下面的就行,最后再import,网上有的就直接Ctrl + C 👻👻
到这里,Java小白成长记(创作笔记二)就结束了,主要给大家讲解了用户登录/注册,认证授权,以及跨域问题.....让我们和小小白一起坚持学习吧🙆🙆♂️
Java小白成长记(创作笔记一)
Java小白成长记(创作笔记一)-CSDN博客
Java小白成长记(创作笔记二)
Java小白成长记(创作笔记二)-CSDN博客