这里面主要设计以下接口:
- 用户登录获取accessToken
- news的增删改查接口
为了保存accessToken,需要引入redis,为了定义返回的json,需要定义公共的JsonResult,下面依次说明
pom.xml添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml增加redis的配置信息
#config Redis
spring:
redis:
host: 127.0.0.1
port: 6379
database: 0
password:
定义redis调用相关类
共包括RedisUtil工具类、RedisKey公共值
@Component
public class RedisUtil {
/**
* 注入的stringRedisTemplate
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* redisTemplate
*/
@Autowired
private RedisTemplate<?, ?> redisTemplate;
/**
* 设置key和对象的value
*
* @param key key
* @param value value
*/
public void set(final String key, Object value) {
final byte[] vbytes = SerializeUtil.serialize(value);
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.set(redisTemplate.getStringSerializer().serialize(key), vbytes);
return null;
}
});
}
/**
* 设置key和value,并加上时间(秒)
*
* @param key key
* @param value value
* @param l 时间
*/
public void set(final String key, Object value, final long l) {
final byte[] vbytes = SerializeUtil.serialize(value);
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.setEx(redisTemplate.getStringSerializer().serialize(key), l, vbytes);
return null;
}
});
}
/**
* 根据key来取值
*
* @param key key
* @param elementType 数据类型
* @param <T> 泛型
* @return 获取的对象
*/
public <T> T get(final String key, Class<T> elementType) {
return redisTemplate.execute(new RedisCallback<T>() {
@Override
public T doInRedis(RedisConnection connection) throws DataAccessException {
byte[] keybytes = redisTemplate.getStringSerializer().serialize(key);
if (connection.exists(keybytes)) {
byte[] valuebytes = connection.get(keybytes);
T value = (T) SerializeUtil.deserialize(valuebytes);
return value;
}
return null;
}
});
}
/**
* 根据key删除该值
*
* @param key key
*/
public void del(final String key) {
final byte[] keyBytes = redisTemplate.getStringSerializer().serialize(key);
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.del(keyBytes);
return null;
}
});
}
}
public class RedisKey {
//用户登录后的accesstoken
public static final String ACCESS_TOKEN = "com:balance:accesstoken";
}
定义公共返回的json对象
public class JsonResult {
/**
* 是否成功
*/
private boolean success;
/**
* 消息
*/
private String message;
/**
* 返回码
*/
private String code;
/**
* 额外的数据
*/
private Object data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public JsonResult(boolean success, String code, Object data) {
this(success, code);
this.data = data;
this.message = ReturnCodeUtil.getMsg(code);
}
public JsonResult() {
}
public JsonResult(boolean success) {
this.success = success;
}
/**
* message通过code获取
*
* @param success
* @param code
*/
public JsonResult(boolean success, String code) {
this(success);
this.code = code;
this.message = ReturnCodeUtil.getMsg(code);
}
/**
* 三个参数,message自己赋值,不通过code获取
*
* @param success
* @param code
* @param message
*/
public JsonResult(boolean success, String code, String message) {
this(success);
this.code = code;
this.message = message;
}
}
这个类用的地方非常多,基本每个controller都会用到,一定要通用、易使用,为了定义公共返回码,还需要定义一个类存储公共的全局返回码,GlobalReturnCode
public class GlobalReturnCode {
/**
* 保存成功
*/
public static final String SAVE_SUCCESS = "10001";
/**
* 删除成功
*/
public static final String DELETE_SUCCESS = "10002";
/**
* 操作成功
*/
public static final String OPERA_SUCCESS = "10003";
/**
* 审核成功
*/
public static final String AUDIT_SUCCESS = "10004";
/**
* 操作失败
*/
public static final String OPERA_FAILURE = "20001";
/**
* 无权限
*/
public static final String NO_AUTH = "30001";
/**
* 系统错误
*/
public static final String SYSTEM_ERROR = "30002";
/**
* 参数错误
*/
public static final String PARAM_ERROR = "30003";
/**
* 路径不存在
*/
public static final String SYSTEM_PATH_NOEXIST = "30004";
}
public class ReturnCodeUtil {
//定义返回码及文字数据
private static Map<String, String> returnCodeMap;
static {
returnCodeMap.put(GlobalReturnCode.SAVE_SUCCESS, "保存成功");
returnCodeMap.put(GlobalReturnCode.DELETE_SUCCESS, "删除成功");
returnCodeMap.put(GlobalReturnCode.OPERA_SUCCESS, "操作成功");
returnCodeMap.put(GlobalReturnCode.AUDIT_SUCCESS, "审核成功");
returnCodeMap.put(GlobalReturnCode.OPERA_FAILURE, "操作失败");
returnCodeMap.put("20102", "账号或密码错误");
returnCodeMap.put(GlobalReturnCode.NO_AUTH, "无权限");
returnCodeMap.put(GlobalReturnCode.SYSTEM_ERROR, "系统错误");
returnCodeMap.put(GlobalReturnCode.PARAM_ERROR, "参数错误");
returnCodeMap.put(GlobalReturnCode.SYSTEM_PATH_NOEXIST, "路径不存在");
}
/**
* 获取返回的中文说明
*
* @param resultCode 返回码
* @return 中文名称
*/
public static String getMsg(String resultCode) {
if (returnCodeMap.containsKey(resultCode)) {
return returnCodeMap.get(resultCode);
} else {
return "";
}
}
}
ReturnCodeUtil
这个类定义类根据返回码获取对应的中文名的方法,实际应用中,可以把固定的返回码存储到数据库中或者配置文件中。
LoginController
@RestController
@RequestMapping("/")
public class LoginControler {
@Autowired
private UserService userService;
@Autowired
private RedisUtil redisUtil;
/**
* 用户登录
*/
@PostMapping("/checkLogin")
public JsonResult checkLogin(HttpServletRequest request, @RequestBody LoginDto loginDto) {
User user = userService.getByUsername(loginDto.getUsername());
if (user != null && user.getPasssword().equals(loginDto.getPassword())) {
//登录成功
String accessToken = UUID.randomUUID().toString();
//放入redis
redisUtil.set(RedisKey.ACCESS_TOKEN + accessToken, user, 30 * 60);
Map<String, String> map = new HashMap<>();
map.put("accessToken", accessToken);
JsonResult jsonResult = new JsonResult(true, GlobalReturnCode.OPERA_SUCCESS, accessToken);
return jsonResult;
} else {
JsonResult jsonResult = new JsonResult(false, "20102");
return jsonResult;
}
}
}
这里面是登录后获取accessToken的代码,统一返回JsonResult。
要说明一点,可以利用@PostMapping
来指定该请求只接收post,简化了以前的RequestMapping设置。用户账号或密码错误,返回
用户登录成功,返回accessToken
NewsController
@RestController
@RequestMapping("/news")
public class NewsController {
@Autowired
private NewsService newsService;
@PostMapping("/add")
public JsonResult add(HttpServletRequest request, @RequestBody News news) {
int flag = newsService.add(news);
if (flag == 1) {
return new JsonResult(true, GlobalReturnCode.SAVE_SUCCESS);
} else {
return new JsonResult(false, GlobalReturnCode.OPERA_FAILURE);
}
}
@PostMapping("/update")
public JsonResult update(HttpServletRequest request, @RequestBody News news) {
int flag = newsService.update(news);
if (flag == 1) {
return new JsonResult(true, GlobalReturnCode.SAVE_SUCCESS);
} else {
return new JsonResult(false, GlobalReturnCode.OPERA_FAILURE);
}
}
@PostMapping("/delete")
public JsonResult delete(HttpServletRequest request, @RequestBody Map<String, String> map) {
int flag = newsService.delete(Integer.parseInt(map.get("id")));
if (flag == 1) {
return new JsonResult(true, GlobalReturnCode.SAVE_SUCCESS);
} else {
return new JsonResult(false, GlobalReturnCode.OPERA_FAILURE);
}
}
@PostMapping("/list")
public JsonResult list(HttpServletRequest request) {
List<News> list = newsService.list();
return new JsonResult(true, GlobalReturnCode.OPERA_SUCCESS, list);
}
@PostMapping("/get")
public JsonResult get(HttpServletRequest request, @RequestBody Map<String, String> map) {
News news = newsService.get(Integer.parseInt(map.get("id")));
return new JsonResult(true, GlobalReturnCode.OPERA_SUCCESS, news);
}
}
这里面比较简单,需要注意的一点就是,传参数即使只包括一个字段,也需要用@RequestBody
来接收