Skip to content

Commit 5756d08

Browse files
committed
chapter 6 end
1 parent be8b816 commit 5756d08

File tree

11 files changed

+588
-37
lines changed

11 files changed

+588
-37
lines changed

images/数据库表.png

1.77 MB
Loading

src/main/java/com/mengxiang/im/push/Application.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mengxiang.im.push;
22

33
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
4+
import com.mengxiang.im.push.provider.GsonProvider;
45
import com.mengxiang.im.push.service.AccountService;
56
import org.glassfish.jersey.server.ResourceConfig;
67

@@ -10,12 +11,12 @@
1011
* @author lbj
1112
*/
1213
public class Application extends ResourceConfig {
13-
public Application(){
14+
public Application() {
1415
//注册逻辑处理的包名
1516
packages(AccountService.class.getPackage().getName());
1617

1718
//注册Json解析器
18-
register(JacksonJsonProvider.class);
19+
register(GsonProvider.class);
1920

2021
//注册日志打印输出
2122
register(Logger.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.mengxiang.im.push.bean.api.account;
2+
3+
import com.google.gson.annotations.Expose;
4+
5+
/**
6+
* @author lbj
7+
* 注册模型
8+
*/
9+
public class RegisterModel {
10+
@Expose
11+
private String account;
12+
@Expose
13+
private String password;
14+
@Expose
15+
private String name;
16+
17+
public String getAccount() {
18+
return account;
19+
}
20+
21+
public void setAccount(String account) {
22+
this.account = account;
23+
}
24+
25+
public String getPassword() {
26+
return password;
27+
}
28+
29+
public void setPassword(String password) {
30+
this.password = password;
31+
}
32+
33+
public String getName() {
34+
return name;
35+
}
36+
37+
public void setName(String name) {
38+
this.name = name;
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.mengxiang.im.push.bean.card;
2+
3+
import com.google.gson.annotations.Expose;
4+
import org.hibernate.annotations.CreationTimestamp;
5+
import org.hibernate.annotations.GenericGenerator;
6+
7+
import javax.persistence.Column;
8+
import javax.persistence.GeneratedValue;
9+
import javax.persistence.Id;
10+
import javax.persistence.PrimaryKeyJoinColumn;
11+
import java.time.LocalDateTime;
12+
13+
public class UserCard {
14+
@Expose
15+
private String id;
16+
@Expose
17+
private String name;
18+
@Expose
19+
private String phone;
20+
@Expose
21+
private String portrait;
22+
@Expose
23+
private String desc;
24+
@Expose
25+
private int sex = 0;
26+
//粉丝数量
27+
@Expose
28+
private int following;
29+
//用户关注人的数量
30+
@Expose
31+
private int followers;
32+
//与当前User关系状态,是否已经关注这个人
33+
@Expose
34+
private int isFollow;
35+
@Expose
36+
//用户信息的最后更新时间
37+
private LocalDateTime modifyAt = LocalDateTime.now();
38+
39+
40+
public String getId() {
41+
return id;
42+
}
43+
44+
public void setId(String id) {
45+
this.id = id;
46+
}
47+
48+
public String getName() {
49+
return name;
50+
}
51+
52+
public void setName(String name) {
53+
this.name = name;
54+
}
55+
56+
public String getPhone() {
57+
return phone;
58+
}
59+
60+
public void setPhone(String phone) {
61+
this.phone = phone;
62+
}
63+
64+
public String getPortrait() {
65+
return portrait;
66+
}
67+
68+
public void setPortrait(String portrait) {
69+
this.portrait = portrait;
70+
}
71+
72+
public String getDesc() {
73+
return desc;
74+
}
75+
76+
public void setDesc(String desc) {
77+
this.desc = desc;
78+
}
79+
80+
public int getSex() {
81+
return sex;
82+
}
83+
84+
public void setSex(int sex) {
85+
this.sex = sex;
86+
}
87+
88+
public int getFollowing() {
89+
return following;
90+
}
91+
92+
public void setFollowing(int following) {
93+
this.following = following;
94+
}
95+
96+
public int getFollowers() {
97+
return followers;
98+
}
99+
100+
public void setFollowers(int followers) {
101+
this.followers = followers;
102+
}
103+
104+
public int getIsFollow() {
105+
return isFollow;
106+
}
107+
108+
public void setIsFollow(int isFollow) {
109+
this.isFollow = isFollow;
110+
}
111+
112+
public LocalDateTime getModifyAt() {
113+
return modifyAt;
114+
}
115+
116+
public void setModifyAt(LocalDateTime modifyAt) {
117+
this.modifyAt = modifyAt;
118+
}
119+
}

src/main/java/com/mengxiang/im/push/bean/db/User.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public class User {
8080
@LazyCollection(LazyCollectionOption.EXTRA)
8181
// 一对多,一个用户可以有很多关注人
8282
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
83-
private Set<UserFollow> myFollowUser = new HashSet<>();
83+
private Set<UserFollow> following = new HashSet<>();
8484

8585

8686
// 关注我的人
@@ -199,12 +199,12 @@ public void setLastReceivedAt(LocalDateTime lastReceivedAt) {
199199
this.lastReceivedAt = lastReceivedAt;
200200
}
201201

202-
public Set<UserFollow> getMyFollowUser() {
203-
return myFollowUser;
202+
public Set<UserFollow> getFollowing() {
203+
return following;
204204
}
205205

206-
public void setMyFollowUser(Set<UserFollow> myFollowUser) {
207-
this.myFollowUser = myFollowUser;
206+
public void setFollowing(Set<UserFollow> following) {
207+
this.following = following;
208208
}
209209

210210
public Set<UserFollow> getFollowers() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.mengxiang.im.push.provider;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.google.gson.stream.JsonReader;
6+
import com.google.gson.stream.JsonWriter;
7+
8+
import javax.ws.rs.Consumes;
9+
import javax.ws.rs.Produces;
10+
import javax.ws.rs.WebApplicationException;
11+
import javax.ws.rs.core.MediaType;
12+
import javax.ws.rs.core.MultivaluedMap;
13+
import javax.ws.rs.ext.MessageBodyReader;
14+
import javax.ws.rs.ext.MessageBodyWriter;
15+
import javax.ws.rs.ext.Provider;
16+
import java.io.*;
17+
import java.lang.annotation.Annotation;
18+
import java.lang.reflect.Type;
19+
import java.nio.charset.Charset;
20+
import java.time.LocalDateTime;
21+
22+
/**
23+
* 用于设置Jersey的Json转换器
24+
* 用于替换JacksonJsonProvider
25+
* <p>
26+
* 该工具类完成了,把Http请求中的请求数据转换为Model实体,
27+
* 同时也实现了把返回的Model实体转换为Json字符串
28+
* 并输出到Http的返回体中。
29+
*
30+
* @param <T> 任意类型范型定义
31+
*/
32+
@Provider
33+
@Produces(MediaType.APPLICATION_JSON)
34+
@Consumes(MediaType.APPLICATION_JSON)
35+
public class GsonProvider<T> implements MessageBodyReader<T>, MessageBodyWriter<T> {
36+
// 共用一个全局的Gson
37+
private static final Gson gson;
38+
39+
static {
40+
// Gson 初始化
41+
GsonBuilder builder = new GsonBuilder()
42+
// 序列化为null的字段
43+
.serializeNulls()
44+
// 仅仅处理带有@Expose注解的变量
45+
.excludeFieldsWithoutExposeAnnotation()
46+
// 支持Map
47+
.enableComplexMapKeySerialization();
48+
// 添加对Java8LocalDateTime时间类型的支持
49+
builder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeConverter());
50+
gson = builder.create();
51+
}
52+
53+
/**
54+
* 取得一个全局的Gson
55+
*
56+
* @return Gson
57+
*/
58+
public static Gson getGson() {
59+
return gson;
60+
}
61+
62+
public GsonProvider() {
63+
}
64+
65+
@Override
66+
public boolean isReadable(Class<?> type, Type genericType,
67+
Annotation[] annotations, MediaType mediaType) {
68+
return true;
69+
}
70+
71+
/**
72+
* 把Json的字符串数据, 转换为T类型的实例
73+
*/
74+
@Override
75+
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
76+
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
77+
InputStream entityStream) throws IOException, WebApplicationException {
78+
try (JsonReader reader = new JsonReader(new InputStreamReader(entityStream, "UTF-8"))) {
79+
return gson.fromJson(reader, genericType);
80+
}
81+
}
82+
83+
@Override
84+
public boolean isWriteable(Class<?> type, Type genericType,
85+
Annotation[] annotations, MediaType mediaType) {
86+
return true;
87+
}
88+
89+
@Override
90+
public long getSize(T t, Class<?> type, Type genericType,
91+
Annotation[] annotations, MediaType mediaType) {
92+
return -1;
93+
}
94+
95+
/**
96+
* 把一个T类的实例输出到Http输出流中
97+
*/
98+
@Override
99+
public void writeTo(T t, Class<?> type, Type genericType, Annotation[] annotations,
100+
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
101+
OutputStream entityStream) throws IOException, WebApplicationException {
102+
//TypeAdapter<T> adapter = gson.getAdapter((TypeToken<T>) TypeToken.get(genericType));
103+
try (JsonWriter jsonWriter = gson.newJsonWriter(new OutputStreamWriter(entityStream, Charset.forName("UTF-8")))) {
104+
gson.toJson(t, genericType, jsonWriter);
105+
jsonWriter.close();
106+
}
107+
}
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.mengxiang.im.push.provider;
2+
3+
import com.google.gson.*;
4+
5+
import java.lang.reflect.Type;
6+
import java.time.LocalDateTime;
7+
import java.time.format.DateTimeFormatter;
8+
import java.util.Locale;
9+
10+
/**
11+
* LocalDateTime 是一个Java8的新时间类型,
12+
* 使用起来比常规的Date更加Nice;
13+
* 但是Gson目前并没有默认支持对LocalDateTime的转换
14+
* <p>
15+
* 该工具类主要是为了解决LocalDateTime与Json字符串相互转换的问题
16+
*
17+
* @author qiujuer Email:qiujuer.live.cn
18+
*/
19+
public class LocalDateTimeConverter implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
20+
/**
21+
* 时间转换的格式为:yyyy-MM-dd'T'HH:mm:ss.SSS
22+
*/
23+
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH);
24+
25+
/**
26+
* 把一个LocalDateTime格式的时间转换为Gson支持的JsonElement
27+
* <p>
28+
* Gson invokes this call-back method during serialization when it encounters a field of the
29+
* specified type. <p>
30+
* <p>
31+
* In the implementation of this call-back method, you should consider invoking
32+
* {@link JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
33+
* non-trivial field of the {@code src} object. However, you should never invoke it on the
34+
* {@code src} object itself since that will cause an infinite loop (Gson will call your
35+
* call-back method again).
36+
*
37+
* @param src the object that needs to be converted to Json.
38+
* @param typeOfSrc the actual type (fully genericized version) of the source object.
39+
* @return a JsonElement corresponding to the specified object.
40+
*/
41+
@Override
42+
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
43+
return new JsonPrimitive(FORMATTER.format(src));
44+
}
45+
46+
/**
47+
* 把一个Gson的JsonElement转换为LocalDateTime时间格式
48+
* <p>
49+
* <p>
50+
* Gson invokes this call-back method during deserialization when it encounters a field of the
51+
* specified type. <p>
52+
* <p>
53+
* In the implementation of this call-back method, you should consider invoking
54+
* {@link JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects
55+
* for any non-trivial field of the returned object. However, you should never invoke it on the
56+
* same type passing {@code json} since that will cause an infinite loop (Gson will call your
57+
* call-back method again).
58+
*
59+
* @param json The Json data being deserialized
60+
* @param typeOfT The type of the Object to deserialize to
61+
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
62+
* @throws JsonParseException if json is not in the expected format of {@code typeOfT}
63+
*/
64+
@Override
65+
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
66+
throws JsonParseException {
67+
return FORMATTER.parse(json.getAsString(), LocalDateTime::from);
68+
}
69+
}

0 commit comments

Comments
 (0)