diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java b/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java index 375cdec..c398018 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java @@ -14,6 +14,10 @@ public class Bkjx { public static final String BKJX_STUDENT_INFO_API = "http://bkjx.wust.edu.cn/jsxsd/grxx/xsxx"; + public static final String BKJX_EXAM_INFO_API = "http://bkjx.wust.edu.cn/jsxsd/kscj/cjcx_list"; + + public static final String BKJX_SCHEME_API = "http://bkjx.wust.edu.cn/jsxsd/pyfa/topyfamx"; + public static class Legacy { public static final String BKJX_INDEX = "http://bkjx.wust.edu.cn"; public static final String BKJX_DATA_STRING_API = "http://bkjx.wust.edu.cn/Logon.do?method=logon&flag=sess"; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/BasicException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/BasicException.java index c894996..07dc6df 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/BasicException.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/BasicException.java @@ -1,4 +1,14 @@ package cn.linghang.mywust.core.exception; public class BasicException extends Exception { + public BasicException() { + } + + public BasicException(String message) { + super(message); + } + + public BasicException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java index 8b037e5..0ef5ef3 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java @@ -1,4 +1,14 @@ package cn.linghang.mywust.core.exception; public class CookieInvalidException extends BasicException { + public CookieInvalidException() { + } + + public CookieInvalidException(String message) { + super(message); + } + + public CookieInvalidException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ParseException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ParseException.java index 92a6ae7..a671ce5 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ParseException.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ParseException.java @@ -1,4 +1,15 @@ package cn.linghang.mywust.core.exception; public class ParseException extends BasicException { + public ParseException() { + super("解析数据失败"); + } + + public ParseException(String message) { + super(message); + } + + public ParseException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/PasswordWornException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/PasswordWornException.java index 09b358e..4afe61b 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/PasswordWornException.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/PasswordWornException.java @@ -1,4 +1,14 @@ package cn.linghang.mywust.core.exception; public class PasswordWornException extends BasicException { + public PasswordWornException() { + } + + public PasswordWornException(String message) { + super(message); + } + + public PasswordWornException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/ExamInfoParser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/ExamInfoParser.java new file mode 100644 index 0000000..1c8fa4f --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/ExamInfoParser.java @@ -0,0 +1,57 @@ +package cn.linghang.mywust.core.parser.undergraduate; + +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.Parser; +import cn.linghang.mywust.core.parser.undergraduate.xpath.ExamInfoXpath; +import cn.linghang.mywust.model.undergrade.ExamInfo; +import org.jsoup.Jsoup; +import org.jsoup.select.Elements; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class ExamInfoParser implements Parser> { + private static final Logger log = LoggerFactory.getLogger(ExamInfoParser.class); + + @Override + public List parse(String html) throws ParseException { + Elements rows = Jsoup.parse(html).selectXpath(ExamInfoXpath.EXAM_INFO_ROWS_XPATH); + if (rows.isEmpty()) { + throw new ParseException(); + } + + List examInfos = new ArrayList<>(rows.size()); + + try { + for (int i = 1; i < rows.size(); i++) { + Elements columns = rows.get(i).getElementsByTag("td"); + + ExamInfo examInfo = new ExamInfo(); + + // 这段看着震撼,但其实很丑 + examInfo.setId(columns.get(0).text()); + examInfo.setTerm(columns.get(1).text()); + examInfo.setCourseNumber(columns.get(2).text()); + examInfo.setCourseName(columns.get(3).text()); + examInfo.setGroupName(columns.get(4).text()); + examInfo.setScore(columns.get(5).text()); + examInfo.setFlag(columns.get(6).text()); + examInfo.setCredit(columns.get(7).text()); + examInfo.setCourseHours(columns.get(8).text()); + examInfo.setGradePoint(columns.get(9).text()); + examInfo.setEvaluateMethod(columns.get(11).text()); + examInfo.setKind(columns.get(12).text()); + examInfo.setCourseKind(columns.get(13).text()); + + examInfos.add(examInfo); + } + } catch (Exception e) { + log.warn("解析成绩页面时发生错误:{}", e.getMessage()); + log.warn("终止解析,返回已解析数据"); + } + + return examInfos; + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/SchemePageParser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/SchemePageParser.java new file mode 100644 index 0000000..1b66711 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/SchemePageParser.java @@ -0,0 +1,19 @@ +package cn.linghang.mywust.core.parser.undergraduate; + +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.Parser; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; + +public class SchemePageParser implements Parser { + + @Override + public String parse(String html) throws ParseException { + Element schemeElement = Jsoup.parse(html).getElementById("dataList"); + if (schemeElement == null) { + throw new ParseException("教学方案html解析提取失败,id为dataList的元素不存在"); + } + + return schemeElement.outerHtml(); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/ExamInfoXpath.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/ExamInfoXpath.java new file mode 100644 index 0000000..cecebeb --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/ExamInfoXpath.java @@ -0,0 +1,5 @@ +package cn.linghang.mywust.core.parser.undergraduate.xpath; + +public class ExamInfoXpath { + public static final String EXAM_INFO_ROWS_XPATH = "//*[@id=\"dataList\"]/tbody/tr"; +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java index f9d9da2..c6769d5 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java @@ -1,7 +1,7 @@ package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.UnionAuth; -import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java index f2ca8e8..b14c3a7 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java @@ -1,7 +1,8 @@ package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.Bkjx; -import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.entitys.FormBodyBuilder; +import cn.linghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; @@ -17,6 +18,28 @@ public class BkjxRequestFactory extends RequestFactory { return makeHttpRequest(Bkjx.BKJX_STUDENT_INFO_API, null, cookies); } + public static HttpRequest examScoreInfoRequest(String cookies, String time, String courseKind, String courseName) { + FormBodyBuilder formBodyBuilder = new FormBodyBuilder(); + // 开课时间 + formBodyBuilder.addQueryParam("kksj", time); + + // 课程性质 + formBodyBuilder.addQueryParam("kcxz", courseKind); + + // 课程名称 + formBodyBuilder.addQueryParam("kcmc", courseName); + + // 显示方式,这里直接选择全部显示 + formBodyBuilder.addQueryParam("xsfs", "all"); + + byte[] postData = formBodyBuilder.buildAndToString().getBytes(StandardCharsets.UTF_8); + return makeHttpRequest(Bkjx.BKJX_EXAM_INFO_API, postData, cookies); + } + + public static HttpRequest schemePageRequest(String cookies) { + return makeHttpRequest(Bkjx.BKJX_SCHEME_API, null, cookies); + } + public static class Legacy { public static HttpRequest dataStringRequest() { return makeHttpRequest(Bkjx.Legacy.BKJX_DATA_STRING_API); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java index 66310fe..d955bd6 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java @@ -1,7 +1,7 @@ package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.Library; -import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpRequest; public class LibraryRequestFactory extends RequestFactory { public static HttpRequest sessionCookieRequest(String serviceTicket) { diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/PhysicsSystemRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/PhysicsSystemRequestFactory.java index a71e986..2a8e40a 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/PhysicsSystemRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/PhysicsSystemRequestFactory.java @@ -1,7 +1,7 @@ package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.PhysicsSystem; -import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java index 0564127..00a1d87 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java @@ -1,8 +1,9 @@ package cn.linghang.mywust.core.request; -import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpRequest; import java.net.URL; +import java.util.Map; public class RequestFactory { protected static final HttpRequest DEFAULT_HTTP_REQUEST = new HttpRequest(); @@ -15,6 +16,10 @@ public class RequestFactory { return makeHttpRequest(url, data, null); } + public static HttpRequest makeHttpRequest(String url, byte[] data, String cookies, Map additionalHeaders) { + return makeHttpRequest(url, data, cookies).addHeaders(additionalHeaders); + } + public static HttpRequest makeHttpRequest(String url, byte[] data, String cookies) { return HttpRequest.builder() .url(makeUrl(url)) diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java index 5e0eb4b..268638d 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java @@ -5,8 +5,8 @@ import cn.linghang.mywust.core.api.UnionAuth; import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.exception.PasswordWornException; import cn.linghang.mywust.core.request.BkjxRequestFactory; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; import cn.linghang.mywust.util.PasswordEncoder; @@ -22,6 +22,11 @@ public class JwcLogin { private final UnionLogin unionLogin; + public JwcLogin(Requester requester) { + this.requester = requester; + this.unionLogin = new UnionLogin(requester); + } + public JwcLogin(Requester requester, UnionLogin unionLogin) { this.requester = requester; this.unionLogin = unionLogin; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java index 4a95373..0e642ba 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java @@ -4,8 +4,8 @@ import cn.linghang.mywust.core.api.Library; import cn.linghang.mywust.core.api.UnionAuth; import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.request.LibraryRequestFactory; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/PhysicsLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/PhysicsLogin.java index 4520e6a..e777979 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/PhysicsLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/PhysicsLogin.java @@ -4,8 +4,8 @@ import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.exception.PasswordWornException; import cn.linghang.mywust.core.parser.physics.PhysicsIndexPageParser; import cn.linghang.mywust.core.request.PhysicsSystemRequestFactory; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; import org.slf4j.Logger; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java index 90c7f80..84d975a 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java @@ -3,8 +3,8 @@ package cn.linghang.mywust.core.service.auth; import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.exception.PasswordWornException; import cn.linghang.mywust.core.request.AuthRequestFactory; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; import cn.linghang.mywust.util.PasswordEncoder; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/ExamInfoApi.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/ExamInfoApi.java new file mode 100644 index 0000000..682e3a7 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/ExamInfoApi.java @@ -0,0 +1,50 @@ +package cn.linghang.mywust.core.service.undergraduate; + +import cn.linghang.mywust.core.exception.CookieInvalidException; +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.undergraduate.ExamInfoParser; +import cn.linghang.mywust.core.request.BkjxRequestFactory; +import cn.linghang.mywust.core.util.BkjxUtil; +import cn.linghang.mywust.model.undergrade.ExamInfo; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.List; + +public class ExamInfoApi { + private static final Logger log = LoggerFactory.getLogger(ExamInfoApi.class); + + private final Requester requester; + + private static final ExamInfoParser parser = new ExamInfoParser(); + + public ExamInfoApi(Requester requester) { + this.requester = requester; + } + + public String getExamInfoPage(String cookies, RequestClientOption requestClientOption) throws IOException, CookieInvalidException { + HttpRequest request = BkjxRequestFactory.examScoreInfoRequest(cookies, "", "", ""); + HttpResponse response = requester.post(request, requestClientOption); + + // 检查响应是否正确 + if (response.getBody() == null || + response.getStatusCode() != HttpResponse.HTTP_OK || + BkjxUtil.checkLoginFinger(response.getBody())) { + + throw new CookieInvalidException("[请求获取成绩]:Cookie无效:" + cookies); + } + + return new String(response.getBody()); + } + + public List getExamInfo(String cookies, RequestClientOption requestClientOption) throws IOException, CookieInvalidException, ParseException { + String examInfoPage = this.getExamInfoPage(cookies, requestClientOption); + + return parser.parse(examInfoPage); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/SchemeApi.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/SchemeApi.java new file mode 100644 index 0000000..284689c --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/SchemeApi.java @@ -0,0 +1,43 @@ +package cn.linghang.mywust.core.service.undergraduate; + +import cn.linghang.mywust.core.exception.CookieInvalidException; +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.undergraduate.SchemePageParser; +import cn.linghang.mywust.core.request.BkjxRequestFactory; +import cn.linghang.mywust.core.util.BkjxUtil; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; + +import java.io.IOException; + +public class SchemeApi { + private final Requester requester; + + private static final SchemePageParser parser = new SchemePageParser(); + + public SchemeApi(Requester requester) { + this.requester = requester; + } + + public String getSchemePage(String cookies, RequestClientOption requestClientOption) throws CookieInvalidException, IOException { + HttpRequest request = BkjxRequestFactory.schemePageRequest(cookies); + HttpResponse response = requester.get(request, requestClientOption); + + // 检查响应是否正确 + if (response.getBody() == null || + response.getStatusCode() != HttpResponse.HTTP_OK || + BkjxUtil.checkLoginFinger(response.getBody())) { + + throw new CookieInvalidException("[请求获取成绩]:Cookie无效:" + cookies); + } + + return new String(response.getBody()); + } + + public String getPrueSchemePage(String cookies, RequestClientOption requestClientOption) throws IOException, CookieInvalidException, ParseException { + String fullPage = this.getSchemePage(cookies, requestClientOption); + return parser.parse(fullPage); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/StudentInfoApi.java similarity index 73% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/StudentInfoApi.java index 5977004..0b256ff 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/StudentInfoApi.java @@ -6,25 +6,20 @@ import cn.linghang.mywust.core.parser.undergraduate.StudentInfoPageParser; import cn.linghang.mywust.core.request.BkjxRequestFactory; import cn.linghang.mywust.core.util.BkjxUtil; import cn.linghang.mywust.model.undergrade.StudentInfo; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import java.io.IOException; -public class JwcService { - private static final Logger log = LoggerFactory.getLogger(JwcService.class); - +public class StudentInfoApi { private final Requester requester; - private final StudentInfoPageParser studentInfoPageParser; + private static final StudentInfoPageParser parser = new StudentInfoPageParser(); - public JwcService(Requester requester, StudentInfoPageParser studentInfoPageParser) { + public StudentInfoApi(Requester requester) { this.requester = requester; - this.studentInfoPageParser = studentInfoPageParser; } public String getStudentInfoPage(String cookies, RequestClientOption requestOption) throws IOException, CookieInvalidException { @@ -45,6 +40,6 @@ public class JwcService { public StudentInfo getStudentInfo(String cookies, RequestClientOption requestOption) throws IOException, CookieInvalidException, ParseException { String studentInfoPage = this.getStudentInfoPage(cookies, requestOption); - return studentInfoPageParser.parse(studentInfoPage); + return parser.parse(studentInfoPage); } } diff --git a/mywust-model/src/main/java/cn/linghang/mywust/model/undergrade/ExamInfo.java b/mywust-model/src/main/java/cn/linghang/mywust/model/undergrade/ExamInfo.java new file mode 100644 index 0000000..c5780fc --- /dev/null +++ b/mywust-model/src/main/java/cn/linghang/mywust/model/undergrade/ExamInfo.java @@ -0,0 +1,88 @@ +package cn.linghang.mywust.model.undergrade; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

考试成绩信息实体类

+ *
+ *

一个对象实体对应着一次考试,也就是系统里边看到的一行成绩

+ *

决定全都用string存储,交给上层调用者自行处理转换

+ *

看似浪费内存,但实际上解析出来的就是string,string转int/float然后又转成其他的什么后其实是更耗内存的

+ *

既然如此不如直接存解析出来的值,具体如何使用就交给上层自行决定

+ * + * @author lensfrex + * @created 2022-10-26 14:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ExamInfo { + /** + * 序号id,在某些场景下可能会有用 + */ + private String id; + + /** + * 学期 + */ + private String term; + + /** + * 课程编号 + */ + private String courseNumber; + + /** + * 课程名称 + */ + private String courseName; + + /** + * 分组名 + */ + private String groupName; + + /** + * 成绩 + */ + private String score; + + /** + * 成绩标识(缺考) + */ + private String flag; + + /** + * 学分 + */ + private String credit; + + /** + * 学时 + */ + private String courseHours; + + /** + * 绩点 + */ + private String gradePoint; + + /** + * 考核方式 + */ + private String evaluateMethod; + + /** + * 考试性质 + */ + private String kind; + + /** + * 课程性质 + */ + private String courseKind; +} diff --git a/mywust-network-okhttp/src/main/java/cn/linghang/mywust/network/okhttp/SimpleOkhttpRequester.java b/mywust-network-okhttp/src/main/java/cn/linghang/mywust/network/okhttp/SimpleOkhttpRequester.java index 3b5155e..75940aa 100644 --- a/mywust-network-okhttp/src/main/java/cn/linghang/mywust/network/okhttp/SimpleOkhttpRequester.java +++ b/mywust-network-okhttp/src/main/java/cn/linghang/mywust/network/okhttp/SimpleOkhttpRequester.java @@ -1,7 +1,7 @@ package cn.linghang.mywust.network.okhttp; -import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.Requester; import cn.linghang.mywust.util.StringUtil; diff --git a/mywust-network/pom.xml b/mywust-network/pom.xml index aadb2b0..9ec51dc 100644 --- a/mywust-network/pom.xml +++ b/mywust-network/pom.xml @@ -23,5 +23,11 @@ lombok 1.18.24 + + cn.linghang + mywust-util + 0.0.1-dev + compile + \ No newline at end of file diff --git a/mywust-network/src/main/java/cn/linghang/mywust/network/Requester.java b/mywust-network/src/main/java/cn/linghang/mywust/network/Requester.java index 273fa94..0ec7494 100644 --- a/mywust-network/src/main/java/cn/linghang/mywust/network/Requester.java +++ b/mywust-network/src/main/java/cn/linghang/mywust/network/Requester.java @@ -1,5 +1,8 @@ package cn.linghang.mywust.network; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; + import java.io.IOException; /** diff --git a/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/FormBodyBuilder.java b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/FormBodyBuilder.java new file mode 100644 index 0000000..6cd63d5 --- /dev/null +++ b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/FormBodyBuilder.java @@ -0,0 +1,41 @@ +package cn.linghang.mywust.network.entitys; + +import cn.linghang.mywust.util.StringUtil; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +public class FormBodyBuilder { + private final Map queryParams; + + public FormBodyBuilder(Map queryParams) { + this.queryParams = queryParams; + } + + public FormBodyBuilder() { + this.queryParams = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + } + + public FormBodyBuilder(int initSize) { + this.queryParams = new HashMap<>(initSize); + } + + public FormBodyBuilder addQueryParams(Map params) { + this.queryParams.putAll(params); + return this; + } + + public FormBodyBuilder addQueryParam(String key, String value) { + this.queryParams.put(key, value); + return this; + } + + public Map build() { + return this.queryParams; + } + + public String buildAndToString() { + return StringUtil.generateQueryString(this.queryParams); + } +} diff --git a/mywust-network/src/main/java/cn/linghang/mywust/network/HttpRequest.java b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpRequest.java similarity index 98% rename from mywust-network/src/main/java/cn/linghang/mywust/network/HttpRequest.java rename to mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpRequest.java index eb7a169..79ed615 100644 --- a/mywust-network/src/main/java/cn/linghang/mywust/network/HttpRequest.java +++ b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpRequest.java @@ -1,4 +1,4 @@ -package cn.linghang.mywust.network; +package cn.linghang.mywust.network.entitys; import lombok.Data; diff --git a/mywust-network/src/main/java/cn/linghang/mywust/network/HttpResponse.java b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpResponse.java similarity index 97% rename from mywust-network/src/main/java/cn/linghang/mywust/network/HttpResponse.java rename to mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpResponse.java index fcbbdc9..8f7e2d8 100644 --- a/mywust-network/src/main/java/cn/linghang/mywust/network/HttpResponse.java +++ b/mywust-network/src/main/java/cn/linghang/mywust/network/entitys/HttpResponse.java @@ -1,4 +1,4 @@ -package cn.linghang.mywust.network; +package cn.linghang.mywust.network.entitys; import lombok.Data; diff --git a/mywust-test/src/test/java/ExamInfoTest.java b/mywust-test/src/test/java/ExamInfoTest.java new file mode 100644 index 0000000..473f53d --- /dev/null +++ b/mywust-test/src/test/java/ExamInfoTest.java @@ -0,0 +1,45 @@ +import cn.linghang.mywust.core.exception.BasicException; +import cn.linghang.mywust.core.service.undergraduate.ExamInfoApi; +import cn.linghang.mywust.model.undergrade.ExamInfo; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; + +import java.io.IOException; +import java.util.List; +import java.util.Scanner; + +public class ExamInfoTest { + public static void main(String[] args) throws BasicException, IOException { + new ExamInfoTest().run(); + } + + private void run() throws BasicException, IOException { + System.out.println("成绩获取"); + System.out.println("Cookie:"); + + Scanner scanner = new Scanner(System.in); + + String cookie = scanner.nextLine(); + + System.out.println("使用Cookie:" + cookie); + + Requester requester = new SimpleOkhttpRequester(); + ExamInfoApi jwcService = new ExamInfoApi(requester); + + RequestClientOption option = new RequestClientOption(); + option.setTimeout(5); + RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); + proxy.setPort(6060); + proxy.setAddress("127.0.0.1"); + option.setProxy(proxy); + option.setFallowUrlRedirect(false); + + List infos = jwcService.getExamInfo(cookie, option); + + for (ExamInfo info : infos) { + + System.out.println(info); + } + } +} diff --git a/mywust-test/src/test/java/JwcLoginTest.java b/mywust-test/src/test/java/JwcLoginTest.java index f416da1..8ddbd41 100644 --- a/mywust-test/src/test/java/JwcLoginTest.java +++ b/mywust-test/src/test/java/JwcLoginTest.java @@ -32,8 +32,11 @@ public class JwcLoginTest { RequestClientOption option = new RequestClientOption(); option.setTimeout(5); - option.setProxy(null); option.setFallowUrlRedirect(false); + RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); + proxy.setPort(6060); + proxy.setAddress("127.0.0.1"); + option.setProxy(proxy); String cookies = jwcLogin.getLoginCookie(username, password, option); diff --git a/mywust-test/src/test/java/SchemeTest.java b/mywust-test/src/test/java/SchemeTest.java new file mode 100644 index 0000000..4fd9b6e --- /dev/null +++ b/mywust-test/src/test/java/SchemeTest.java @@ -0,0 +1,43 @@ +import cn.linghang.mywust.core.exception.BasicException; +import cn.linghang.mywust.core.service.undergraduate.ExamInfoApi; +import cn.linghang.mywust.core.service.undergraduate.SchemeApi; +import cn.linghang.mywust.model.undergrade.ExamInfo; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; + +import java.io.IOException; +import java.util.List; +import java.util.Scanner; + +public class SchemeTest { + public static void main(String[] args) throws BasicException, IOException { + new SchemeTest().run(); + } + + private void run() throws BasicException, IOException { + System.out.println("培养方案获取"); + System.out.println("Cookie:"); + + Scanner scanner = new Scanner(System.in); + + String cookie = scanner.nextLine(); + + System.out.println("使用Cookie:" + cookie); + + RequestClientOption option = new RequestClientOption(); + option.setTimeout(5); + RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); + proxy.setPort(6060); + proxy.setAddress("127.0.0.1"); + option.setProxy(proxy); + option.setFallowUrlRedirect(false); + + Requester requester = new SimpleOkhttpRequester(); + SchemeApi jwcService = new SchemeApi(requester); + + String page = jwcService.getPrueSchemePage(cookie, option); + + System.out.println(page); + } +} diff --git a/mywust-test/src/test/java/StudentInfoPageTest.java b/mywust-test/src/test/java/StudentInfoPageTest.java new file mode 100644 index 0000000..23baa3d --- /dev/null +++ b/mywust-test/src/test/java/StudentInfoPageTest.java @@ -0,0 +1,41 @@ +import cn.linghang.mywust.core.exception.BasicException; +import cn.linghang.mywust.core.parser.undergraduate.StudentInfoPageParser; +import cn.linghang.mywust.core.service.auth.JwcLogin; +import cn.linghang.mywust.core.service.auth.UnionLogin; +import cn.linghang.mywust.core.service.undergraduate.StudentInfoApi; +import cn.linghang.mywust.model.undergrade.StudentInfo; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; + +import java.io.IOException; +import java.util.Scanner; + +public class StudentInfoPageTest { + public static void main(String[] args) throws BasicException, IOException { + new StudentInfoPageTest().run(); + } + + private void run() throws BasicException, IOException { + System.out.println("学生信息获取"); + System.out.println("Cookie:"); + + Scanner scanner = new Scanner(System.in); + + String cookie = scanner.nextLine(); + + System.out.println("使用Cookie:" + cookie); + + Requester requester = new SimpleOkhttpRequester(); + StudentInfoApi jwcService = new StudentInfoApi(requester); + + RequestClientOption option = new RequestClientOption(); + option.setTimeout(5); + option.setProxy(null); + option.setFallowUrlRedirect(false); + + StudentInfo info = jwcService.getStudentInfo(cookie, option); + + System.out.println(info); + } +}