牛客中级项目笔记 · 业务开发要点记录

  • 密码加盐

将用户密码加上一段随机字符串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. 包目录相同
  2. 文件名相同(注意: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的类)。

 

转载于:https://my.oschina.net/u/3943244/blog/3081834

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值