在开始编码前,先建立几个Package(可以按个人习惯命名),如图
1.Controllers 用于存放控制器类
2.Models 用于存放数据实体类
3.Repositories 用于存放数据库操作接口
4. Services 用于存放业务逻辑类
5. Tools用于存放工具类
-----------------------------------------------------------------------------------------------------------------------------
一、建立User实体类
首先在Models下新建名为User.java的实体类,
代码如下
1 @Entity //实体注入2 @Table(name = "sys_user") //映射对应表明3 public classUser {4 @Id //主键Id5 @GeneratedValue(strategy =GenerationType.IDENTITY)6 privateLong id;7 privateString userName;8 privateString hashedPassword;9
10 //省略getter和setter11
12 //重写toString方法便于后期调试查看数据
13 @Override14 publicString toString() {15 return "User{" +
16 "id=" + id +
17 ", userName='" + userName + '\'' +
18 ", hashedPassword='" + hashedPassword + '\'' +
19 '}';20 }21 }
二、新建CrudRepostory接口
在Repositories下新建一个名为UserRepository的接口,需要继承CrudRepository
CrudRepository是包含基础增删改查操作的Repository
public interface UserRepository extends CrudRepository{
}
其中不需要添加任何自定义方法就可以实现基础的数据库操作
三、新建用户登录操作业务类
在Services下新建UserService.java
1 @Service2 public classUserService {3 //Autowire装配UserRepository数据库操作类
4 @Autowired5 UserRepository userRepository;6
7 /**
8 * 基础登录逻辑9 *@paramuserName 用户名10 *@parampassword MD5 hashed密码11 *@return
12 */
13 public booleanlogin(String userName,String password){14 Iterable users =userRepository.findAll();15 for(User u:16 users) {17 if(u.getUserName().equals(userName) &&u.getHashedPassword().equals(password)){18 return true;19 }20 }21 return false;22 }23 }
很简单一个操作类,就不多作说明了
@Service注解表示这是一个Service类
四、建立Controller
在Controllers下建立UserController.java
1 @RestController2 @RequestMapping(value = "/api/account")3 public classUserController {4 @Autowired5 UserService userService;6 @RequestMapping(value = "/login/{username}/{password}",method =RequestMethod.GET)7 public boolean login(@PathVariable("username") String userName,@PathVariable("password") String password){8 returnuserService.login(userName,password);9 }10 }
@RequestMapping 路由地址
@RestController 注解表示这是一个RESTController
@PathVariable 表示这是一个路由变量
-------------------------------------------------------------------------------------------------------------------------------------------
没什么问题保存后,就可以调试运行了
运行成功后,打开PostMan 通过Get方法访问我们的 http://localhost:8080/api/account/login/admin/admin
发送请求,由于我们数据库中没有任何数据,返回false
下边我们改造一下我们的登录结构,并为数据库添加一下基础数据
首先在UserRepository.java添加一个getByUserName方法
1 public interface UserRepository extends CrudRepository{2 //根据用户名查找用户
3 OptionalgetByUserName(String userName);4 }
为了返回指定格式数据,我们还要在Models下建立一个Result.java
1 public class Result{2 privateInteger errCode;3 privateString errMessage;4 privateT data;5
6 //省略getter和setter
7 @Override8 publicString toString() {9 return "Result{" +
10 "errCode=" + errCode +
11 ", errMessage='" + errMessage + '\'' +
12 ", data=" + data +
13 '}';14 }15 }
修改UserService.java,修改登录逻辑,增加添加初始数据
1 @Service2 public classUserService {3 //Autowire装配UserRepository数据库操作类
4 @Autowired5 UserRepository userRepository;6
7 /**
8 * 基础登录逻辑9 *@paramuserName 用户名10 *@parampassword MD5 hashed密码11 *@return
12 */
13 public Resultlogin(String userName, String password){14 Result result = new Result<>();15 User u =userRepository.getByUserName(userName).get();16 if(u == null){17 result.setErrCode(-1);18 result.setErrMessage("用户不存在");19 }else if(u.getHashedPassword().equals(password)){20 System.out.println(u.toString());21 result.setErrCode(0);22 result.setData(u.getId());23 }else{24 result.setErrCode(1);25 result.setErrMessage("密码错误");26 }27 returnresult;28 }29
30 public Resultadd(User user){31 Result result = new Result<>();32 User u =userRepository.save(user);33 if(u != null){34 result.setErrCode(0);35 result.setData(u);36 }else{37 result.setErrCode(-1);38 result.setErrMessage("发生错误");39 }40 returnresult;41 }42
43 public voidinitUserData(){44 Iterable users =userRepository.findAll();45 int sum = 0;46 while(users.iterator().hasNext()){47 users.iterator().next();48 sum++;49 }50 if(sum == 0){51 for (int i = 0; i < 5; i++){52 User user = newUser();53 user.setUserName("Admin" +i);54 String hashedPassword = Encrypt.stringMD5("Admin" +i);55 user.setHashedPassword(hashedPassword);56 add(user);57 }58 }59
60 }
其中用到的MD5加密类在Tools路径中,代码如下
importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;public classEncrypt {public staticString stringMD5(String input) {try{//拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
MessageDigest messageDigest =MessageDigest.getInstance("MD5");//输入的字符串转换成字节数组
byte[] inputByteArray =input.getBytes();//inputByteArray是输入字符串转换得到的字节数组
messageDigest.update(inputByteArray);//转换并返回结果,也是字节数组,包含16个元素
byte[] resultByteArray =messageDigest.digest();//字符数组转换成字符串返回
returnbyteArrayToHex(resultByteArray);
}catch(NoSuchAlgorithmException e) {return null;
}
}public static String byteArrayToHex(byte[] byteArray) {//首先初始化一个字符数组,用来存放每个16进制字符
char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F'};//new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
char[] resultCharArray =new char[byteArray.length * 2];//遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
int index = 0;for (byteb : byteArray) {
resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b& 0xf];
}//字符数组组合成字符串返回
return newString(resultCharArray);
}
}
在UserController中增加一个初始化数据路由方法
@RequestMapping(value = "/",method =RequestMethod.GET)public voidinitData(){
userService.initUserData();
}
调试运行项目
PostMan先请求 http://localhost:8080/api/account/
查看数据库,发现初始数据已经添加进来了
我们继续测试一下Login方法吧
(1)请求正确数据 http://localhost:8080/api/account/login/Admin1/2E33A9B0B06AA0A01EDE70995674EE23
返回
{
"errCode": 0,
"errMessage": null,
"data": 2
}
返回正确
(2)请求错误数据 http://localhost:8080/api/account/login/Admin1/2E33A9B0B06A
返回
{
"errCode": 1,
"errMessage": "密码错误",
"data": null
}
返回密码错误,也符合我们的结果
(3)请求不存在用户数据 http://localhost:8080/api/account/login/blogn/2E33A9B0B06AA0A01EDE70995674
返回
{
"timestamp": "2018-07-17T13:52:24.082+0000",
"status": 500,
"error": "Internal Server Error",
"message": "No value present",
"path": "/api/account/login/blogn/2E33A9B0B06AA0A01EDE70995674"
}
系统自动返回500状态码,不符合预期,但也可以作参考,影响不大
我们简单的用户登录系统及这样了,其实我们还可以加入用户注册方法,大家可以自行尝试,我这里就不下了
以后的代码可能没这么详细了,只对重点代码做解释
希望给大家做一个参考