Compare commits
No commits in common. 'fe8fe5cc22a6321f11419e8b68c4c13a6284c1e1' and 'bf828e3418a802f095cc6f3a5ce913bd922b7458' have entirely different histories.
fe8fe5cc22
...
bf828e3418
@ -1,20 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class PagingResult<T> { |
||||
private int currentPage; |
||||
private int pageSize; |
||||
private int totalPage; |
||||
|
||||
private int totalResult; |
||||
|
||||
private T data; |
||||
} |
@ -1,61 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.origin; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* 响应回来的书籍信息(借阅历史,当前借阅,即将逾期等的书目字段) |
||||
*/ |
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class BaseLoanBook { |
||||
protected String bibId; |
||||
|
||||
protected String title; |
||||
|
||||
protected String author; |
||||
|
||||
/** |
||||
* 借书时间 |
||||
*/ |
||||
protected String loanDate; |
||||
|
||||
protected String location; |
||||
|
||||
protected String barCode; |
||||
|
||||
/** |
||||
* 图书属性信息 |
||||
*/ |
||||
@JsonProperty("bibAttrs") |
||||
protected BookAttribute bookAttribute; |
||||
|
||||
/** |
||||
* 图书属性 |
||||
*/ |
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public static class BookAttribute { |
||||
protected String isbn; |
||||
|
||||
protected String publisher; |
||||
|
||||
@JsonProperty("pub_year") |
||||
protected String publishYear; |
||||
|
||||
protected String price; |
||||
|
||||
/** |
||||
* 索书号 |
||||
*/ |
||||
@JsonProperty("callno") |
||||
protected String callNumber; |
||||
|
||||
/** |
||||
* 书类编号 |
||||
*/ |
||||
@JsonProperty("classno") |
||||
protected String classNumber; |
||||
} |
||||
} |
@ -1,67 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.origin; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
@Data |
||||
public class BookSearchRequest { |
||||
private List<Object> filterFieldList = new ArrayList<>(); |
||||
private String collapseField = "groupId"; |
||||
private String sortType = "desc"; |
||||
private String indexName = "idx.opac"; |
||||
private String sortField = "relevance"; |
||||
|
||||
private List<QueryFieldListItem> queryFieldList = new ArrayList<>(1); |
||||
|
||||
private int pageSize; |
||||
private int page; |
||||
|
||||
public BookSearchRequest(String keyWord, int pageSize, int page) { |
||||
this.pageSize = pageSize; |
||||
this.page = page; |
||||
this.queryFieldList.add(new QueryFieldListItem(keyWord)); |
||||
} |
||||
|
||||
@Data |
||||
public static class QueryFieldListItem { |
||||
private String field = "all"; |
||||
private String operator = "*"; |
||||
private int logic = 0; |
||||
|
||||
private List<String> values = new ArrayList<>(1); |
||||
|
||||
public QueryFieldListItem(String keyWord) { |
||||
values.add(keyWord); |
||||
} |
||||
} |
||||
|
||||
public static class Builder { |
||||
private int pageSize; |
||||
private int page; |
||||
private String keyword; |
||||
|
||||
private Builder() { |
||||
} |
||||
|
||||
public Builder pageSize(int pageSize) { |
||||
this.pageSize = pageSize; |
||||
return this; |
||||
} |
||||
|
||||
public Builder page(int page) { |
||||
this.page = page; |
||||
return this; |
||||
} |
||||
|
||||
public Builder keyword(String keyword) { |
||||
this.keyword = keyword; |
||||
return this; |
||||
} |
||||
|
||||
public BookSearchRequest build() { |
||||
return new BookSearchRequest(keyword, pageSize, page); |
||||
} |
||||
} |
||||
} |
@ -1,80 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.origin; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.parsed.BookHolding; |
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class BookSearchResult { |
||||
private String bibId; |
||||
|
||||
private String title; |
||||
|
||||
private String author; |
||||
|
||||
@JsonProperty("abstract") |
||||
private String summary; |
||||
|
||||
private String publisher; |
||||
|
||||
private List<String> holdingTypes; |
||||
|
||||
@JsonProperty("callno") |
||||
private List<String> callNumber; |
||||
|
||||
/** |
||||
* 文献类型 |
||||
*/ |
||||
private String docType; |
||||
|
||||
private String groupId; |
||||
|
||||
private String isbn; |
||||
|
||||
/** |
||||
* 图书馆系统中的图书编号 |
||||
*/ |
||||
private String bibNo; |
||||
|
||||
/** |
||||
* 图书总数 |
||||
*/ |
||||
private int itemCount; |
||||
|
||||
/** |
||||
* 在借数量 |
||||
*/ |
||||
private int circCount; |
||||
|
||||
@JsonProperty("pub_year") |
||||
private String pubYear; |
||||
|
||||
@JsonProperty("classno") |
||||
private String classNumber; |
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY) |
||||
private List<BookHolding> holdings; |
||||
} |
||||
|
||||
/* |
||||
bibId: 图书馆系统中的图书ID,用于唯一标识一本图书。 |
||||
holdingTypes: 图书的持有类型,此处为“print”,表示该图书以纸质形式持有。 |
||||
author: 作者,此处为“Walter Savitch著”,表示该图书的作者是Walter Savitch。 |
||||
callno: 索书号,此处为["TP312JA/E26=4/1","TP312JA/E26=4/2"],表示该图书的索书号是TP312JA/E26=4/1和TP312JA/E26=4/2。 |
||||
docType: 文献类型,此处为“doc.02”,表示该图书的文献类型为“doc.02”。 |
||||
groupId: 分组ID,此处为“1e24652f1d98f0586dc6468136f8eba6”,可能是用于图书分类的一个标识。 |
||||
isbn: ISBN号,此处为“7115152888 (v. 1)”,表示该图书的ISBN号是7115152888,其中“(v. 1)”可能表示版本号。 |
||||
bibNo: 图书馆系统中的图书编号,此处为“1800067256”。 |
||||
title: 书名,此处为“Java : an introduction to problem solving & programming = Java : 程序设计与问题解决/ Walter Savitch著.”,表示该图书的书名是“Java : 程序设计与问题解决”,作者是Walter Savitch。 |
||||
itemCount: 图书总数,此处为8,表示该图书馆系统中该图书的总数。 |
||||
circCount: 图书当前在借数量,此处也为8,表示该图书当前在借数量为8。 |
||||
pub_year: 出版年份,此处为“2006.”,表示该图书的出版年份是2006年。 |
||||
classno: 分类号,此处为“TP312JA”,可能是用于图书分类的一个标识。 |
||||
publisher: 出版商,此处为“Posts & Telecom Press”,表示该图书的出版商是Posts & Telecom Press。 |
||||
holdings: 持有情况,此处为空字符串,可能是用于记录该图书的其他持有情况。 |
||||
_id: 记录ID,此处为“544237”,可能是用于记录该图书的唯一标识。 |
||||
*/ |
@ -1,12 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.origin; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class CurrentLoanBook extends BaseLoanBook { |
||||
private String dueDate; |
||||
} |
@ -1,12 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.origin; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
@Data |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class HistoryLoanBook extends BaseLoanBook { |
||||
private String returnDate; |
||||
} |
@ -1,51 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.parsed; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Builder; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 书籍详情 |
||||
*/ |
||||
@Data |
||||
@Builder |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class BookDetail { |
||||
private String title; |
||||
private String author; |
||||
private String isbn; |
||||
|
||||
/** |
||||
* 作者介绍 |
||||
*/ |
||||
private String authorDescribe; |
||||
|
||||
/** |
||||
* 目录 |
||||
*/ |
||||
private String catalog; |
||||
|
||||
/** |
||||
* 封面url |
||||
*/ |
||||
private String coverUrl; |
||||
|
||||
/** |
||||
* 图书简要 |
||||
*/ |
||||
private String summary; |
||||
|
||||
/** |
||||
* 图书介绍 |
||||
*/ |
||||
private String introduction; |
||||
|
||||
/** |
||||
* 书籍详细信息,因为图书馆系统奇葩的中文不定key,因此将这些信息放入key-value对中,需要者自取 |
||||
*/ |
||||
Map<String, String> extraInfoMap; |
||||
} |
@ -1,56 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.parsed; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* 馆藏信息(单个) |
||||
*/ |
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class BookHolding { |
||||
@JsonProperty("callNo") |
||||
private String callNumber; |
||||
|
||||
/** |
||||
* 馆藏总数 |
||||
*/ |
||||
private int itemsCount; |
||||
|
||||
/** |
||||
* 可借数 |
||||
*/ |
||||
private int itemsAvailable; |
||||
|
||||
/** |
||||
* 条形码 |
||||
*/ |
||||
private String barCode; |
||||
|
||||
/** |
||||
* 所属馆藏地 |
||||
*/ |
||||
private String location; |
||||
|
||||
/** |
||||
* 临时馆藏地 |
||||
*/ |
||||
private String tempLocation; |
||||
|
||||
/** |
||||
* 卷年期 |
||||
*/ |
||||
@JsonProperty("vol") |
||||
private String volume; |
||||
|
||||
/** |
||||
* 馆名(总馆等等) |
||||
*/ |
||||
private String library; |
||||
|
||||
/** |
||||
* 状态文本 |
||||
*/ |
||||
private String status; |
||||
} |
@ -1,69 +0,0 @@ |
||||
package cn.wustlinghang.mywust.data.library.parsed; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
@Data |
||||
@JsonIgnoreProperties(ignoreUnknown = true) |
||||
public class BookSearchResult { |
||||
private String bibId; |
||||
|
||||
private List<String> holdingTypes; |
||||
private String author; |
||||
|
||||
private List<String> callNumber; |
||||
|
||||
/** |
||||
* 文献类型 |
||||
*/ |
||||
private String docType; |
||||
private String groupId; |
||||
private String isbn; |
||||
|
||||
/** |
||||
* 图书馆系统中的图书编号 |
||||
*/ |
||||
private String bibNo; |
||||
|
||||
private String title; |
||||
|
||||
/** |
||||
* 图书总数 |
||||
*/ |
||||
private int itemCount; |
||||
|
||||
/** |
||||
* 在借数量 |
||||
*/ |
||||
private int circCount; |
||||
|
||||
private String pubYear; |
||||
|
||||
private String classNumber; |
||||
|
||||
private String publisher; |
||||
|
||||
private List<BookHolding> holdings; |
||||
} |
||||
|
||||
/* |
||||
bibId: 图书馆系统中的图书ID,用于唯一标识一本图书。 |
||||
holdingTypes: 图书的持有类型,此处为“print”,表示该图书以纸质形式持有。 |
||||
author: 作者,此处为“Walter Savitch著”,表示该图书的作者是Walter Savitch。 |
||||
callno: 索书号,此处为["TP312JA/E26=4/1","TP312JA/E26=4/2"],表示该图书的索书号是TP312JA/E26=4/1和TP312JA/E26=4/2。 |
||||
docType: 文献类型,此处为“doc.02”,表示该图书的文献类型为“doc.02”。 |
||||
groupId: 分组ID,此处为“1e24652f1d98f0586dc6468136f8eba6”,可能是用于图书分类的一个标识。 |
||||
isbn: ISBN号,此处为“7115152888 (v. 1)”,表示该图书的ISBN号是7115152888,其中“(v. 1)”可能表示版本号。 |
||||
bibNo: 图书馆系统中的图书编号,此处为“1800067256”。 |
||||
title: 书名,此处为“Java : an introduction to problem solving & programming = Java : 程序设计与问题解决/ Walter Savitch著.”,表示该图书的书名是“Java : 程序设计与问题解决”,作者是Walter Savitch。 |
||||
itemCount: 图书总数,此处为8,表示该图书馆系统中该图书的总数。 |
||||
circCount: 图书当前在借数量,此处也为8,表示该图书当前在借数量为8。 |
||||
pub_year: 出版年份,此处为“2006.”,表示该图书的出版年份是2006年。 |
||||
classno: 分类号,此处为“TP312JA”,可能是用于图书分类的一个标识。 |
||||
publisher: 出版商,此处为“Posts & Telecom Press”,表示该图书的出版商是Posts & Telecom Press。 |
||||
holdings: 持有情况,此处为空字符串,可能是用于记录该图书的其他持有情况。 |
||||
_id: 记录ID,此处为“544237”,可能是用于记录该图书的唯一标识。 |
||||
*/ |
@ -0,0 +1,40 @@ |
||||
package cn.wustlinghang.mywust.core.request.factory.library.request; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.StringJoiner; |
||||
|
||||
@Data |
||||
public class SearchRequest { |
||||
private final List<Object> filterFieldList = new ArrayList<>(); |
||||
private final String collapseField = "groupId"; |
||||
private final String sortType = "desc"; |
||||
private final String indexName = "idx.opac"; |
||||
private final String sortField = "relevance"; |
||||
|
||||
private final List<QueryFieldListItem> queryFieldList = new ArrayList<>(1); |
||||
|
||||
private int pageSize; |
||||
private int page; |
||||
|
||||
public SearchRequest(String keyWord, int pageSize, int page) { |
||||
this.pageSize = pageSize; |
||||
this.page = page; |
||||
this.queryFieldList.add(new QueryFieldListItem(keyWord)); |
||||
} |
||||
|
||||
@Data |
||||
public static class QueryFieldListItem { |
||||
private final String field = "all"; |
||||
private final String operator = "*"; |
||||
private final int logic = 0; |
||||
|
||||
private final List<String> values = new ArrayList<>(1); |
||||
|
||||
public QueryFieldListItem(String keyWord) { |
||||
values.add(keyWord); |
||||
} |
||||
} |
||||
} |
@ -1,82 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook; |
||||
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook; |
||||
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook; |
||||
import cn.wustlinghang.mywust.data.library.parsed.BookHolding; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JsonParser; |
||||
import com.fasterxml.jackson.core.JsonToken; |
||||
import com.fasterxml.jackson.databind.DeserializationContext; |
||||
import com.fasterxml.jackson.databind.DeserializationFeature; |
||||
import com.fasterxml.jackson.databind.JavaType; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.fasterxml.jackson.databind.deser.std.StringDeserializer; |
||||
import com.fasterxml.jackson.databind.module.SimpleModule; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
public abstract class BaseLibraryApiService { |
||||
protected static final ObjectMapper objectMapper = new ObjectMapper(); |
||||
|
||||
static { |
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); |
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
||||
SimpleModule module = new SimpleModule(); |
||||
module.addDeserializer(String.class, new SpecialStringDeserializer()); |
||||
objectMapper.registerModule(module); |
||||
} |
||||
|
||||
protected static final JavaType loanBookListType = |
||||
objectMapper.getTypeFactory().constructParametricType(List.class, BaseLoanBook.class); |
||||
|
||||
protected static final JavaType historyLoanBookListType = |
||||
objectMapper.getTypeFactory().constructParametricType(List.class, HistoryLoanBook.class); |
||||
|
||||
protected static final JavaType currentLoanBookListType = |
||||
objectMapper.getTypeFactory().constructParametricType(List.class, CurrentLoanBook.class); |
||||
|
||||
protected static final JavaType bookSearchResultListType = |
||||
objectMapper.getTypeFactory().constructParametricType(List.class, BookSearchResult.class); |
||||
|
||||
protected static final JavaType bookHoldingListType = |
||||
objectMapper.getTypeFactory().constructParametricType(List.class, BookHolding.class); |
||||
|
||||
protected final Requester requester; |
||||
|
||||
public BaseLibraryApiService(Requester requester) { |
||||
this.requester = requester; |
||||
} |
||||
|
||||
public void checkResponse(HttpResponse response) throws ApiException { |
||||
// 检查响应是否正确
|
||||
if (response.getStatusCode() != 200) { |
||||
throw new ApiException(ApiException.Code.COOKIE_INVALID); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* <p>继承自原版StringDeserializer,特殊定制的字符串反序列化器</p> |
||||
* <p>测试时偶然发现的图书馆搜索api返回的json中`pub_year`和`abstract`等一些本应该是字符串值的字段有概率会出现为空数组的奇葩情况...</p> |
||||
* <p>想了半天也没想明白那系统究竟是怎么在字符串里蹦出`[]`的...</p> |
||||
*/ |
||||
class SpecialStringDeserializer extends StringDeserializer { |
||||
@Override |
||||
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { |
||||
// The critical path: ensure we handle the common case first.
|
||||
if (p.hasToken(JsonToken.VALUE_STRING)) { |
||||
return p.getText(); |
||||
} |
||||
// [databind#381]
|
||||
if (p.hasToken(JsonToken.START_ARRAY)) { |
||||
// 仅修改了这行
|
||||
return p.getValueAsString(""); |
||||
} |
||||
return _parseString(p, ctxt, this); |
||||
} |
||||
} |
@ -1,55 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.*; |
||||
|
||||
public class BookCoverImageUrlApiService extends BaseLibraryApiService { |
||||
public BookCoverImageUrlApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public List<String> getBookCoverImageUrl(String isbn) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbn); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
// 因为只查了一本书,所以path(isbn)直接一步到位就行了
|
||||
JsonNode imageResultJson = objectMapper.readTree(response.getBody()).path("data").path(isbn); |
||||
List<String> covers = new ArrayList<>(imageResultJson.size()); |
||||
for (JsonNode resultItemJson : imageResultJson) { |
||||
covers.add(resultItemJson.path("imageUrl").asText()); |
||||
} |
||||
|
||||
return covers; |
||||
} |
||||
|
||||
public Map<String, List<String>> getBookCoverImageUrl(List<String> isbnList) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbnList); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
JsonNode data = objectMapper.readTree(response.getBody()).path("data"); |
||||
Map<String, List<String>> result = new HashMap<>(data.size()); |
||||
|
||||
// 遍历data下每本书
|
||||
Iterator<Map.Entry<String, JsonNode>> it = data.fields(); |
||||
while (it.hasNext()) { |
||||
Map.Entry<String, JsonNode> bookItemJson = it.next(); |
||||
List<String> covers = new ArrayList<>(bookItemJson.getValue().size()); |
||||
for (JsonNode resultItemJson : bookItemJson.getValue()) { |
||||
covers.add(resultItemJson.path("imageUrl").asText()); |
||||
} |
||||
|
||||
result.put(bookItemJson.getKey(), covers); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
} |
@ -1,69 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.parsed.BookDetail; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import cn.wustlinghang.mywust.util.StringUtil; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
|
||||
public class BookDetailApiService extends BaseLibraryApiService { |
||||
public BookDetailApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public BookDetail getBookDetail(String bookId) throws ApiException, IOException { |
||||
HttpRequest infoRequest = LibraryRequestFactory.bookInfoRequest(bookId); |
||||
HttpResponse infoResponse = requester.get(infoRequest); |
||||
checkResponse(infoResponse); |
||||
|
||||
JsonNode data = objectMapper.readTree(infoResponse.getBody()) |
||||
.path("data").path("map"); |
||||
|
||||
JsonNode baseInfo = data.path("baseInfo").path("map"); |
||||
JsonNode detailInfo = data.path("detailInfo").path("map"); |
||||
|
||||
Map<String, String> extraInfoMap = new HashMap<>(detailInfo.size()); |
||||
Iterator<Map.Entry<String, JsonNode>> it = detailInfo.fields(); |
||||
while (it.hasNext()) { |
||||
Map.Entry<String, JsonNode> field = it.next(); |
||||
extraInfoMap.put(field.getKey(), StringUtil.cleanHtml(field.getValue().asText("无"))); |
||||
} |
||||
|
||||
String isbn = baseInfo.get("isbn").asText("无"); |
||||
String author = baseInfo.path("author").asText("无"); |
||||
String title = baseInfo.path("title").asText("无"); |
||||
|
||||
HttpRequest doubanInfoRequest = LibraryRequestFactory.bookDoubanInfoRequest(isbn); |
||||
HttpResponse doubanInfoResponse = requester.get(doubanInfoRequest); |
||||
checkResponse(doubanInfoResponse); |
||||
|
||||
JsonNode doubanInfo = objectMapper.readTree(doubanInfoResponse.getBody()).path("data"); |
||||
String authorDescribe = doubanInfo.path("authorInfo").asText("无"); |
||||
String catalog = doubanInfo.path("catalog").asText("无"); |
||||
String summary = doubanInfo.path("content").asText("无"); |
||||
String introduction = doubanInfo.path("intro").asText(summary); |
||||
String coverUrl = doubanInfo.path("imageUrl").asText(""); |
||||
|
||||
return BookDetail.builder() |
||||
.isbn(isbn) |
||||
.author(author) |
||||
.title(title) |
||||
.extraInfoMap(extraInfoMap) |
||||
|
||||
.authorDescribe(StringUtil.cleanHtml(authorDescribe)) |
||||
.catalog(StringUtil.cleanHtml(catalog)) |
||||
.summary(StringUtil.cleanHtml(summary)) |
||||
.introduction(StringUtil.cleanHtml(introduction)) |
||||
.coverUrl(coverUrl) |
||||
|
||||
.build(); |
||||
} |
||||
} |
@ -1,39 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.parsed.BookHolding; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.exception.ParseException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JacksonException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
public class BookHoldingApiService extends BaseLibraryApiService { |
||||
|
||||
|
||||
public BookHoldingApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public List<BookHolding> getHoldingList(String id) |
||||
throws ApiException, IOException, ParseException { |
||||
|
||||
HttpRequest loanRequest = LibraryRequestFactory.bookHoldingRequest(id); |
||||
HttpResponse loanResponse = requester.get(loanRequest); |
||||
checkResponse(loanResponse); |
||||
try { |
||||
JsonNode data = objectMapper.readTree(loanResponse.getBody()).path("data"); |
||||
// 这里的holding是个string值,需要独立解析(坑人)
|
||||
JsonNode holdings = data.path("holdings"); |
||||
|
||||
return objectMapper.readValue(holdings.asText("[]"), bookHoldingListType); |
||||
} catch (JacksonException e) { |
||||
throw new ParseException(e.getMessage(), ""); |
||||
} |
||||
} |
||||
} |
@ -1,52 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.exception.ParseException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JacksonException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
public class CurrentLoanApiService extends BaseLibraryApiService { |
||||
public CurrentLoanApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public PagingResult<List<CurrentLoanBook>> getCurrentLoan(String cookie, int page, int pageSize) |
||||
throws ApiException, IOException, ParseException { |
||||
|
||||
HttpRequest loanRequest = LibraryRequestFactory.currentLoanRequest(cookie, page, pageSize); |
||||
HttpResponse loanResponse = requester.get(loanRequest); |
||||
checkResponse(loanResponse); |
||||
try { |
||||
JsonNode data = objectMapper.readTree(loanResponse.getBody()).path("data"); |
||||
|
||||
// 获取,计算分页数据
|
||||
pageSize = data.path("pageSize").asInt(pageSize); |
||||
int currentPage = data.path("currentPage").asInt(page); |
||||
int totalResult = data.path("total").asInt(0); |
||||
int totalPage = data.path("totalPage").asInt(0); |
||||
|
||||
JsonNode itemsJson = data.path("items"); |
||||
List<CurrentLoanBook> books = objectMapper.treeToValue(itemsJson, currentLoanBookListType); |
||||
|
||||
return PagingResult.<List<CurrentLoanBook>>builder() |
||||
.currentPage(currentPage) |
||||
.totalResult(totalResult) |
||||
.pageSize(pageSize) |
||||
.totalPage(totalPage) |
||||
.data(books) |
||||
.build(); |
||||
|
||||
} catch (JacksonException e) { |
||||
throw new ParseException(e.getMessage(), ""); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,66 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* 图书馆相关接口,由于返回的数据都是json,特别好解析,所以这里的数据获取到了之后可以直接拿来用,自己来解析 |
||||
*/ |
||||
public class LibraryApiService extends LibraryApiServiceBase { |
||||
public LibraryApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public String search(String keyword, int page, int pageSize) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.bookSearchRequest(keyword, page, pageSize); |
||||
HttpResponse response = requester.post(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
|
||||
public String getBookDetail(String bookId) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.bookInfoRequest(bookId); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
|
||||
public String getBookCoverImageUrl(String isbn) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbn); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
|
||||
public String getOverdueSoon(String cookie) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.overdueSoonRequest(cookie); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
|
||||
public String getCurrentLoan(String cookie) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.currentLoanRequest(cookie); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
|
||||
public String getLoanHistory(String cookie) throws ApiException, IOException { |
||||
HttpRequest request = LibraryRequestFactory.loanHistoryRequest(cookie); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
|
||||
return response.getStringBody(); |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
|
||||
public abstract class LibraryApiServiceBase { |
||||
protected final Requester requester; |
||||
|
||||
public LibraryApiServiceBase(Requester requester) { |
||||
this.requester = requester; |
||||
} |
||||
|
||||
public void checkResponse(HttpResponse response) throws ApiException { |
||||
// 检查响应是否正确
|
||||
if (response.getStatusCode() != 200) { |
||||
throw new ApiException(ApiException.Code.COOKIE_INVALID); |
||||
} |
||||
} |
||||
} |
@ -1,53 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.exception.ParseException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JacksonException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
public class LoanHistoryApiService extends BaseLibraryApiService { |
||||
|
||||
public LoanHistoryApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public PagingResult<List<HistoryLoanBook>> getLoanHistory(String cookie, int page, int pageSize) |
||||
throws ApiException, IOException, ParseException { |
||||
|
||||
HttpRequest request = LibraryRequestFactory.loanHistoryRequest(cookie, page, pageSize); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
try { |
||||
JsonNode data = objectMapper.readTree(response.getBody()).path("data"); |
||||
|
||||
// 获取,计算分页数据
|
||||
pageSize = data.path("pageSize").asInt(pageSize); |
||||
int currentPage = data.path("currentPage").asInt(page); |
||||
int totalResult = data.path("total").asInt(0); |
||||
int totalPage = data.path("totalPage").asInt(0); |
||||
|
||||
JsonNode itemsJson = data.path("items"); |
||||
List<HistoryLoanBook> books = objectMapper.treeToValue(itemsJson, historyLoanBookListType); |
||||
|
||||
return PagingResult.<List<HistoryLoanBook>>builder() |
||||
.currentPage(currentPage) |
||||
.totalResult(totalResult) |
||||
.pageSize(pageSize) |
||||
.totalPage(totalPage) |
||||
.data(books) |
||||
.build(); |
||||
|
||||
} catch (JacksonException e) { |
||||
throw new ParseException(e.getMessage(), ""); |
||||
} |
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.exception.ParseException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JacksonException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
@Slf4j |
||||
public class OverdueSoonApiService extends BaseLibraryApiService { |
||||
public OverdueSoonApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public PagingResult<List<BaseLoanBook>> getOverdueSoon(String cookie, int page, int pageSize) |
||||
throws ApiException, IOException, ParseException { |
||||
|
||||
HttpRequest request = LibraryRequestFactory.overdueSoonRequest(cookie, page, pageSize); |
||||
HttpResponse response = requester.get(request); |
||||
checkResponse(response); |
||||
try { |
||||
// todo 这里即将到期书籍字段跟当前借阅和借阅历史字段格式貌似有点不太一样(data字段是个数组)
|
||||
// 但是目前手上没有样本,因此这里还需要再测试测试
|
||||
JsonNode data = objectMapper.readTree(response.getBody()).path("data"); |
||||
|
||||
// 获取,计算分页数据
|
||||
pageSize = data.path("pageSize").asInt(pageSize); |
||||
int currentPage = data.path("currentPage").asInt(page); |
||||
int totalResult = data.path("total").asInt(0); |
||||
int totalPage = data.path("totalPage").asInt(0); |
||||
|
||||
JsonNode itemsJson = data.path("items"); |
||||
List<BaseLoanBook> baseLoanBooks = objectMapper.treeToValue(itemsJson, loanBookListType); |
||||
|
||||
return PagingResult.<List<BaseLoanBook>>builder() |
||||
.currentPage(currentPage) |
||||
.totalResult(totalResult) |
||||
.pageSize(pageSize) |
||||
.totalPage(totalPage) |
||||
.data(baseLoanBooks) |
||||
.build(); |
||||
|
||||
} catch (JacksonException e) { |
||||
throw new ParseException(e.getMessage(), ""); |
||||
} |
||||
} |
||||
} |
@ -1,68 +0,0 @@ |
||||
package cn.wustlinghang.mywust.core.request.service.library; |
||||
|
||||
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; |
||||
import cn.wustlinghang.mywust.data.library.PagingResult; |
||||
import cn.wustlinghang.mywust.data.library.origin.BookSearchRequest; |
||||
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult; |
||||
import cn.wustlinghang.mywust.data.library.parsed.BookHolding; |
||||
import cn.wustlinghang.mywust.exception.ApiException; |
||||
import cn.wustlinghang.mywust.exception.ParseException; |
||||
import cn.wustlinghang.mywust.network.Requester; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpRequest; |
||||
import cn.wustlinghang.mywust.network.entitys.HttpResponse; |
||||
import com.fasterxml.jackson.core.JacksonException; |
||||
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class SearchApiService extends BaseLibraryApiService { |
||||
public SearchApiService(Requester requester) { |
||||
super(requester); |
||||
} |
||||
|
||||
public PagingResult<List<BookSearchResult>> search(String keyword, int page, int pageSize) |
||||
throws ApiException, IOException, ParseException { |
||||
return search(new BookSearchRequest(keyword, pageSize, page)); |
||||
} |
||||
|
||||
public PagingResult<List<BookSearchResult>> search(BookSearchRequest request) |
||||
throws ApiException, IOException, ParseException { |
||||
HttpRequest searchRequest = LibraryRequestFactory.bookSearchRequest(request); |
||||
HttpResponse searchResponse = requester.post(searchRequest); |
||||
checkResponse(searchResponse); |
||||
|
||||
try { |
||||
JsonNode data = objectMapper.readTree(searchResponse.getBody()).path("data"); |
||||
|
||||
int pageSize = data.path("limit").asInt(request.getPageSize()); |
||||
int currentPage = data.path("offset").asInt(request.getPage()) / pageSize + 1; |
||||
int totalResult = data.path("actualTotal").asInt(0); |
||||
int totalPage = totalResult / pageSize + 1; |
||||
|
||||
JsonNode dataList = data.get("dataList"); |
||||
List<BookSearchResult> books = new ArrayList<>(dataList.size()); |
||||
for (JsonNode item : dataList) { |
||||
// 反序列化holding字段,原字段为字符串值,无法直接原样转换
|
||||
List<BookHolding> holdings = objectMapper.readValue( |
||||
item.path("holdings").asText("[]"), bookHoldingListType); |
||||
BookSearchResult book = objectMapper.treeToValue(item, BookSearchResult.class); |
||||
book.setHoldings(holdings); |
||||
books.add(book); |
||||
} |
||||
|
||||
return PagingResult.<List<BookSearchResult>>builder() |
||||
.currentPage(currentPage) |
||||
.totalResult(totalResult) |
||||
.pageSize(pageSize) |
||||
.totalPage(totalPage) |
||||
.data(books) |
||||
.build(); |
||||
|
||||
} catch (JacksonException e) { |
||||
e.printStackTrace(); |
||||
throw new ParseException(e.getMessage(), ""); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue