GitHub地址:https://github.com/vicotorz/zhangdizhihu
開發流程:DataBase-->Model-->Dao-->Service-->Controller-->Test
SQL 建表語句:
評論:comment
id int(11),
content text,
user_id int(11),
entity_id int(11),
entity_type int(11),
created_date datetime,
status int(1)index 'entity-index' ('entity-id' ASC,'entity-type' ASC)
feed流:feed流
id int(11),
created_date datetime,
user_id int(11),
data tinytext,
type int(11)index 'user_index' ('user_id' ASC)
登陸狀態:login_ticket
id int(11),
user_id int(11),
ticket varchar(45),
expired datetime,
status int(11)
消息:message
id int(11),
from_id int(11),
to_id int(11),
content text,
created_date datetime,
has_read int(11),
conversation_id varchar(45)index 'conversation_index' ('conversation_id' ASC)
index 'created_date' ('created_date' ASC)
問題:question
id int(11),
title varchar(255),
content text,
user_id int(11),
created_date datetime,
comment_count int(11)index 'date_index' ('created_date' ASC)
用戶: user
id int(11),
name varchar(64),
password varchar(128),
salt varchar(32),
head_url varchar(56),primary key('id')
unique key 'name' ('name')
MyBatis:
- application.properties增加數據庫連接等配置
- pom.xml引入my-spring-boot-starter、mysql-connector-java
- mybatis-config.xml新增mybatis使用規則
- 複雜的sql寫DAO.xml
Fastjson:
jsonObject 傳入到Ajax的js中,例如unfllow的json,傳入到detail.js中
Redis:
數據結構 | 指令 |
List | lpush(異步隊列放入事件)、lpop、blpop、 lindex、lrange、lindex、lrem、linsert、 lset、rpush |
Set | sdiff、smembers(獲取狀態)、sinter、scard(點贊)、 srem(消除踩)、sadd |
SortedSet | zadd(添加關注)、zscore、zrange(獲取粉絲)、 zcount、zrank、zrevrank、zrem(取消關注) |
Hash | hset、hget、hgetAll、hexists、hkeys、hvals |
異步框架:
存入格式:EVENTQUEUE:
{actorId:12, entityId:6910,entityOwnerId:12,entityType:1,exts:{},type:FLLOW}
代碼結構:
//fireEvent
public boolean fireEvent(EventModal eventModal){
String json = JSONObject.toJSONString(eventModal);
String key = RedisKeyUtil.getEventQueuekey();
jedisAdapter.lpush(key,json);
return true;
}
EventModel{
EventType type;//Event類型
actorId;//執行用戶id
entityType;//entity類型
entityId;//entity id
entityOwnerId;//entity 擁有者id
}
Event Consumer方法:
afterPropertiesSet把一個Handler關心的事件放在config
Map<String,EventHandler> beans = applicationContext.getBeansOfType(EventHandler.class);
- beans內容格式爲:(addHandler,com.zhihu.async.handler.AddQuestionHandler)
- 取beans.getValue().getSupportEventTypes()內容
- 添加ADD_QUESTION,com.zhihu.async.handler.AddQuestionHandler
開啓線程把優先隊列的事件取出來,還原Event
- Thread一直從JedisPool中取有EVENTQUEUE的事件,若沒有EVENT_QUEUE字樣,表明是新事件
- 還原EVNET JSON.parseobject(message,EventModel.class)
- 若config中沒有字樣,不能識別
- for(EventHandler handler = config.get(eventModel.getType())) handler.dohandle(eventModel);
在config中找誰處理這個EventHandler
用戶登陸流程:
- StringUtils.isBlank
- 生成用戶token,加鹽:UUID.randomUUID();
- 密碼 + 鹽 的MD5加密
- 設置有效期expired
記錄登陸狀態:
Cookie cookie = new Cookie("ticket",map.get("ticket"));
cookie.setPath("/");
response.addCookie(cookie);
return "redirect:/";
敏感詞內部:{五={星={紅={旗={isEnd=1},isEnd=0},isEnd=0},isEnd=0},isEnd=0}
攔截器:鏈路回調思想,攔截HttpServletRequest
@Component,implements HandlerInterceptor:preHandler、postHandler、afterCompletion
定義Hostholder(使用ThreadLocal)
extends WebMvcConfiguration:註冊定義好的攔截器
WendaConfiguration extends WebMvcConfiguraAdapter{
@Autowired
void addInterceptors(InterceptorRefistry registry){
registry.addInterceptor(...).addPathPatterns(...);
}
}
Timeline功能:(1)推-redis (2)拉-數據庫
代碼涉及:EventHandler、FeedDao、Service、Modal、Controller、Redis 隊列存儲
- 觸發事件後放入異步隊列
- 調用FeedDao存入
- 把這個事件推給所有粉絲,並放入到RedisAdapter中
- 顯示:從Jedis中取feed(lrange),若feed在數據庫中,則加入顯示
郵件功能:
- 開啓pop3 / STMP 服務
- 加入Java mail依賴
- 編寫實現類:JavaMailSenderImpl(設置name,password,Host,Port,Protocal,encoding)
- 調用:mailSender,sendWithHTMLTemplate(model.getExt("email"),"...",模板)
Solr:
solr_url = "http://...";
HttpSolrClient client = new HttpSolrClient.Builder(solr_url).build();
//查詢
SolrQuery query = new SolrQuery(keywrod);
QueryResponse response = client.query(query);
//建索引
SolrInputDocument doc = new SolrInputDocument();
doc.setField("","");
UpdateResponse response = client(doc,...);
七牛雲SDK上傳:
- 設置七牛keys
- 設置上傳空間:buketname
- 祕鑰配置:Auth auth = Auth.create(ACCESS_KEY,SECRET_KEY);
- 設置上傳對象:UploadManager uploadManager = new UploadManager();
- 設置七牛域名
- 開始上傳:auth.uploadToken(bucketname);
- 上傳圖片(使用到MultipartFile)