-
密码加盐
将用户密码加上一段随机字符串salt,再进行md5加密得到password,salt和password保存到数据库,安全性更高。
下次用户登录时,使用用户输入的的密码加上对应的salt,进行md5加密得到的字符串,和数据库的password进行比对即可。
-
ViewObject对象
方便传递任何数据到页面
public class ViewObject {
private Map<String, Object> objs = new HashMap<String, Object>();
public void set(String key, Object value) {
objs.put(key, value);
}
public Object get(String key) {
return objs.get(key);
}
}
-
springboot整合mybatis的坑
springboot整合mybatis时,如果使用xml写sql语句,则xml需要和接口:
- 包目录相同
- 文件名相同(注意:1、为xml新建folder时名字不能加点.,需要一级一级的新建;2、Mapper接口中对应的方法的参数需要用@Param注解才能绑定)
-
ThreadLocal的使用场景
使用ThreadLocal临时存储用户信息(结合登录拦截器使用):
public class HostHolder {
//可能有多个用户
//每条线程set之后,get的只能是自己之前set的数据
private static ThreadLocal<User> users = new ThreadLocal<User>();
public User getUser() {
return users.get();
}
public void setUser(User user) {
users.set(user);
}
public void clear() {
users.remove();
}
}
/**
* 登录拦截器,拦截Controller,获取已登录用户信息
*
* @author Xing
*
*/
@Component
public class PassportInterceptor implements HandlerInterceptor {
@Autowired
private LoginTicketDAO loginTicketDAO;
@Autowired
private UserDAO userDAO;
@Autowired
private HostHolder hostHolder;
// 请求处理之前
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
throws Exception {
String ticket = null;
if (httpServletRequest.getCookies() != null) {
for (Cookie cookie : httpServletRequest.getCookies()) {
if (cookie.getName().equals("ticket")) {
ticket = cookie.getValue();
break;
}
}
}
if (ticket != null) {
LoginTicket loginTicket = loginTicketDAO.selectByTicket(ticket);
if (loginTicket == null || loginTicket.getExpired().before(new Date()) || loginTicket.getStatus() != 0) {
return true;
}
// ticket有效
User user = userDAO.selectById(loginTicket.getUserId());
hostHolder.setUser(user);
}
return true;
}
// 请求处理之后,视图返回之前
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null && hostHolder.getUser() != null) {
// 渲染页面需要
modelAndView.addObject("user", hostHolder.getUser());
}
}
// 视图返回之后
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
hostHolder.clear();
}
}
-
七牛云存储示例
@RequestMapping("/test")
public String show2(Model model, MultipartFile file) throws IOException {
// 七牛上传
System.out.println("七牛");
// 构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
// ...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
// ...生成上传凭证,然后准备上传
String accessKey = "72CXf4pr3125puKUkvI5_fV0SlInPqs6e4LYUdgelw";
String secretKey = "dEgiOAAamICu13M__U0l-ME10XfOVR2IX2GHWSShuF";
String bucket = "xing";
// 默认不指定key的情况下,以文件内容的hash值作为文件名
String key = (String) UUID.randomUUID().toString().subSequence(0, 5);
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
byte[] bytes = file.getBytes();
try {
Response response = uploadManager.put(bytes, key, upToken);
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
// ignore
}
}
model.addAttribute("test", "12312312313");
return "index";
}
-
评论功能开发
Comment表有entity_id,entity_type字段,用来描述它关联的业务对象,entity_id表示被评论的对象id,entity_type表示被评论对象的类型。
EntityType类,表示被评论的是新闻或他人的评论,或者是其他的东西。
public class EntityType {
public static int ENTITY_NEWS = 1;
public static int ENTITY_COMMENT = 2;
}
-
redis的应用场景
String(KV):单一数值, 验证码,PV(page view),缓存
操作:set setex incr
Hash:对象属性 ,不定长属性数
操作:hset hget hgetAll hexists hkeys hvals
List:双向列表,适用的业务:最新列表,关注列表
操作:lpush lpop blpop lindex lrange lrem linsert lset rpus
Set:适用于无顺序的集合,点赞点踩,抽奖,已读, 共同好友
操作:sdiff smembers sinter scard
SortedSet:排行榜, 优先队列
操作:zadd zscore zrange zcount zrank zrevrank
踩坑:spring boot的controller中方法如果是void不返回视图,会报错templateException,所以必须有返回值
springboot整合redis有两种方案:一是使用springboot的整合包(需要配置类、操作redis的类),二是使用redis官方包(只需要操作redis的类)。