From 1c12977744be4521333638b849bb61b2347c9051 Mon Sep 17 00:00:00 2001 From: Hoelee Date: Fri, 2 Oct 2020 15:55:44 +0800 Subject: [PATCH] Enabled WebApp POM --- nb-configuration.xml | 26 ++ pom.xml | 116 +++-- .../java/com/hoelee/demo/DemoApplication.java | 13 - .../demo/controller/RootController.java | 18 - .../com/hoelee/demo/demo/DemoApplication.java | 79 ++++ .../java/com/hoelee/demo/demo/MvcConfig.java | 67 +++ .../hoelee/demo/demo/ServletInitializer.java | 12 + .../demo/demo/controller/HomeController.java | 434 ++++++++++++++++++ .../demo/demo/controller/TestController.java | 84 ++++ .../com/hoelee/demo/demo/entity/Comment.java | 105 +++++ .../com/hoelee/demo/demo/entity/Post.java | 199 ++++++++ .../exception/ExceptionJSONConversion.java | 36 ++ .../demo/demo/helper/InternetHelper.java | 222 +++++++++ .../hoelee/demo/demo/helper/ListHelper.java | 56 +++ src/main/resources/application.properties | 9 + src/main/resources/rebel.xml | 21 + src/main/resources/templates/testing.html | 16 + src/main/webapp/META-INF/context.xml | 2 + .../webapp/WEB-INF/thymeleaf/testing.html | 16 + .../demo/demo/DemoApplicationTests.java | 11 +- 20 files changed, 1459 insertions(+), 83 deletions(-) create mode 100644 nb-configuration.xml delete mode 100644 src/main/java/com/hoelee/demo/DemoApplication.java delete mode 100644 src/main/java/com/hoelee/demo/controller/RootController.java create mode 100644 src/main/java/com/hoelee/demo/demo/DemoApplication.java create mode 100644 src/main/java/com/hoelee/demo/demo/MvcConfig.java create mode 100644 src/main/java/com/hoelee/demo/demo/ServletInitializer.java create mode 100644 src/main/java/com/hoelee/demo/demo/controller/HomeController.java create mode 100644 src/main/java/com/hoelee/demo/demo/controller/TestController.java create mode 100644 src/main/java/com/hoelee/demo/demo/entity/Comment.java create mode 100644 src/main/java/com/hoelee/demo/demo/entity/Post.java create mode 100644 src/main/java/com/hoelee/demo/demo/exception/ExceptionJSONConversion.java create mode 100644 src/main/java/com/hoelee/demo/demo/helper/InternetHelper.java create mode 100644 src/main/java/com/hoelee/demo/demo/helper/ListHelper.java create mode 100644 src/main/resources/rebel.xml create mode 100644 src/main/resources/templates/testing.html create mode 100644 src/main/webapp/META-INF/context.xml create mode 100644 src/main/webapp/WEB-INF/thymeleaf/testing.html rename src/test/java/com/{hoelele => hoelee}/demo/demo/DemoApplicationTests.java (54%) diff --git a/nb-configuration.xml b/nb-configuration.xml new file mode 100644 index 0000000..e4cf0f1 --- /dev/null +++ b/nb-configuration.xml @@ -0,0 +1,26 @@ + + + + + + Tomcat + /less:/css + false + false + + + /scss:/css + false + 1.7-web + + diff --git a/pom.xml b/pom.xml index c87e286..1f6c46d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,55 +1,77 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.3.4.RELEASE - - - com.hoelele.demo - demo - 0.0.1-SNAPSHOT - demo - Demo project for Spring Boot + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.4.RELEASE + + + com.hoelee + demo + 0.0.1-SNAPSHOT + war + demo + Demo project for Spring Boot - - 1.8 - + + 1.8 + - - - org.springframework.boot - spring-boot-starter - + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - org.springframework - spring-web - 5.2.3.RELEASE - jar - - + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + org.json + json + jar + 20200518 + + + com.squareup.okhttp3 + okhttp + jar + + + org.thymeleaf + thymeleaf + jar + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/src/main/java/com/hoelee/demo/DemoApplication.java b/src/main/java/com/hoelee/demo/DemoApplication.java deleted file mode 100644 index b34b7ab..0000000 --- a/src/main/java/com/hoelee/demo/DemoApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.hoelee.demo; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class DemoApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } - -} diff --git a/src/main/java/com/hoelee/demo/controller/RootController.java b/src/main/java/com/hoelee/demo/controller/RootController.java deleted file mode 100644 index 08f271a..0000000 --- a/src/main/java/com/hoelee/demo/controller/RootController.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hoelee.demo.controller; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - - -@Controller -@RequestMapping(value = "/admin") -public class RootController { - - @ResponseBody - @GetMapping(value = {"","/"}) - public String index(){ - return "Hello world"; - } -} diff --git a/src/main/java/com/hoelee/demo/demo/DemoApplication.java b/src/main/java/com/hoelee/demo/demo/DemoApplication.java new file mode 100644 index 0000000..f6678f1 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/DemoApplication.java @@ -0,0 +1,79 @@ +package com.hoelee.demo.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; +import org.thymeleaf.templateresolver.DefaultTemplateResolver; +import org.thymeleaf.templateresolver.ServletContextTemplateResolver; + +/** + *

Class desc:

+ * + * + * @version v2, 2020-09-30 12:01:49AM + * @author hoelee + */ +@SpringBootApplication +@EnableAutoConfiguration +@EnableConfigurationProperties +@ComponentScan({"com.hoelee.demo.demo.controller", "com.hoelee.demo.demo.helper"}) +public class DemoApplication { + + private static TemplateEngine templateEngine; + + /** hoelee v2 2020-09-30 12:01:49AM + *

Method desc:

+ * + * + * @param args + */ + public static void main(String[] args) { + SpringApplication springApplication = new SpringApplication(); + ApplicationContext appCtx = springApplication.run(DemoApplication.class, args); + } + /** hoelee v2 2020-09-30 03:54:52AM + *

Method desc:

+ * + @Bean + public TemplateResolver templateResolver() { + TemplateResolver templateResolver = new ClassLoaderTemplateResolver(); + + //templateResolver.setCacheable(false); + //templateResolver.setTemplateMode("XHTML"); // Default + templateResolver.setPrefix("/WEB-INF/thymeleaf/"); + templateResolver.setCacheTTLMs(3600000L); + templateResolver.setSuffix(".html"); + templateResolver.setTemplateMode("HTML5"); + return templateResolver; + } + + * @return + private static void initializeTemplateEngine() { + ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(); + + // XHTML is the default mode, but we set it anyway for better understanding of code + templateResolver.setTemplateMode("XHTML"); + + // This will convert "home" to "/WEB-INF/templates/home.html" + templateResolver.setPrefix("/WEB-INF/thymeleaf/"); + templateResolver.setSuffix(".html"); + + // Template cache TTL=1h. If not set, entries would be cached until expelled by LRU + templateResolver.setCacheTTLMs(3600000L); + + //templateResolver.setCacheable(false); + templateEngine = new TemplateEngine(); + + templateEngine.setTemplateResolver(templateResolver); + } + */ +} + +//~ v2, 2020-09-30 05:26:41AM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/MvcConfig.java b/src/main/java/com/hoelee/demo/demo/MvcConfig.java new file mode 100644 index 0000000..b5a932d --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/MvcConfig.java @@ -0,0 +1,67 @@ +package com.hoelee.demo.demo; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; + +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.spring5.ISpringTemplateEngine; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.view.ThymeleafViewResolver; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ITemplateResolver; +import org.thymeleaf.templateresolver.ServletContextTemplateResolver; + +import javax.servlet.ServletContext; + +/** + *

Class desc:

+ * + * + * @version v2, 2020-09-30 05:59:17AM + * @author hoelee + */ +@Configuration +@EnableWebMvc +public class MvcConfig { + + @Autowired + private TemplateEngine templateEngine; + @Autowired + private ServletContext servletContext; + + @Bean + private void initializeTemplateEngine() { + ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext); + + // HTML is the default mode, but we set it anyway for better understanding of code + templateResolver.setTemplateMode(TemplateMode.HTML); + + // This will convert "home" to "/WEB-INF/templates/home.html" + templateResolver.setPrefix("/WEB-INF/thymeleaf/"); + templateResolver.setSuffix(".html"); + + // Template cache TTL=1h. If not set, entries would be cached until expelled + templateResolver.setCacheTTLMs(Long.valueOf(3600000L)); + + // Cache is set to true by default. Set to false if you want templates to + // be automatically updated when modified. + templateResolver.setCacheable(true); + + this.templateEngine = new TemplateEngine(); + + this.templateEngine.setTemplateResolver(templateResolver); + } +} + +//~ v2, 2020-09-30 05:59:17AM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/ServletInitializer.java b/src/main/java/com/hoelee/demo/demo/ServletInitializer.java new file mode 100644 index 0000000..28975f6 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/ServletInitializer.java @@ -0,0 +1,12 @@ +package com.hoelee.demo.demo; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +public class ServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(DemoApplication.class); + } +} diff --git a/src/main/java/com/hoelee/demo/demo/controller/HomeController.java b/src/main/java/com/hoelee/demo/demo/controller/HomeController.java new file mode 100644 index 0000000..4a8ce96 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/controller/HomeController.java @@ -0,0 +1,434 @@ +package com.hoelee.demo.demo.controller; + +import com.hoelee.demo.demo.entity.Comment; +import com.hoelee.demo.demo.entity.Post; +import com.hoelee.demo.demo.helper.InternetHelper; +import com.hoelee.demo.demo.helper.ListHelper; + +import okhttp3.Authenticator; +import okhttp3.Call; +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.Credentials; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; + +import org.json.JSONArray; +import org.json.JSONObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + *

Class desc:

+ * + * @version v2, 2020-09-30 03:02:39AM + * @author hoelee + */ +@Controller +@RequestMapping(value = "", method = {RequestMethod.GET, RequestMethod.POST}) +public class HomeController { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + // + @Autowired + private InternetHelper internetHelper; + + @ResponseBody + @GetMapping({"", "/"}) + private String home() { + return "Hello World"; + } + + @ResponseBody + @GetMapping("/post/topComment") + private String question1TopCommentEndPoint() { + List postList = internetHelper.readAllPosts(); + List commentList = internetHelper.readAllComments(); + + // Distribute respective Comment into each Post + for(int a = 0; a < postList.size(); a++) { + Post post = postList.get(a); + List commentListCurrentPost = new LinkedList<>(); + + for(int b = 0; b < commentList.size(); b++) { + Comment comment = commentList.get(b); + + if (comment.getPostId() == post.getId()) + commentListCurrentPost.add(comment); + } + + post.setCommentList(commentListCurrentPost); + } + + // Sort Post by highest number of comment + Collections.sort(postList, + new Comparator() { + + @Override + public int compare(Post post1, Post post2) { + int post1CommentSize = post1.getCommentList().size(); + int post2CommentSize = post2.getCommentList().size(); + + return post2CommentSize - post1CommentSize; + } + + }); + + // Response JSONArray + JSONArray root = new JSONArray(); + + for(int a = 0; a < postList.size(); a++) { + root.put(postList.get(a).toJSONObjectCustomResponse1()); + } + + return root.toString(); + } + + /** hoelee v2 2020-10-02 12:40:33PM + *

Method desc:

+ * + * + * @param postId + * @param commentId + * @param name + * @param email + * @param body + * @param operator - provide 'and', 'or' + * @return + */ + @ResponseBody + @GetMapping("/search") + private String question2SearchComment( // + @RequestParam(value = "postId", required = false) String postId, // + @RequestParam(value = "commentId", required = false) String commentId, // + @RequestParam(value = "name", required = false) String name, // + @RequestParam(value = "email", required = false) String email, // + @RequestParam(value = "body", required = false) String body, // + @RequestParam(value = "operator", required = false) String operator // + ) { + List commentList = internetHelper.readAllComments(); + + // Default no filter handler + if ((postId == null) && (commentId == null) && (name == null) && (email == null) && (body == null)) { + + // Response JSONArray + JSONArray root = new JSONArray(); + + for(int a = 0; a < commentList.size(); a++) { + root.put(commentList.get(a).toJSONObject()); + } + + return root.toString(); + } + + // Check operator + boolean operatorAnd = false; + boolean operatorOr = false; + + if (!((operator == null) || operator.isEmpty())) { + operator = operator.toLowerCase(); + + if (operator == "and") + operatorAnd = true; + if (operator == "or") + operatorOr = true; + } else { + + // Default Operator + operatorOr = true; + } + + // Start the search + if (operatorOr) { + + // Do operator OR + List commentListPostId = new LinkedList<>(); + List commnetListCommentId = new LinkedList<>(); + List commentListName = new LinkedList<>(); + List commentListEmail = new LinkedList<>(); + List commentListBody = new LinkedList<>(); + List commentListResult = new LinkedList<>(); + + if (!((postId == null) || postId.isEmpty())) { + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + int postIdInt = Integer.parseInt(postId); + + if (comment.getPostId() == postIdInt) + commentListPostId.add(comment); + } + } + + if (!((commentId == null) || commentId.isEmpty())) { + + // Remove unrelated comment id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + int commentIdInt = Integer.parseInt(commentId); + + if (comment.getId() == commentIdInt) + commnetListCommentId.add(comment); + } + } + + if (!((name == null) || name.isEmpty())) { + + // Remove unrelated comment id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getName().contains(name)) + commentListName.add(comment); + } + } + + if (!((email == null) || email.isEmpty())) { + + // Remove unrelated comment id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getEmail().contains(email)) + commentListEmail.add(comment); + } + } + + if (!((body == null) || body.isEmpty())) { + + // Remove unrelated comment id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getBody().contains(body)) + commentListBody.add(comment); + } + } + + // Remove duplicate Comment + Set commentSetResult = new HashSet<>(); + + commentListResult.addAll(commentListPostId); + commentListResult.addAll(commnetListCommentId); + commentListResult.addAll(commentListName); + commentListResult.addAll(commentListEmail); + commentListResult.addAll(commentListBody); + + for(int a = 0; a < commentListResult.size(); a++) { + commentSetResult.add(commentListResult.get(a)); + } + + // Response JSONArray + JSONArray root = new JSONArray(); + + for(Comment cmt : commentSetResult) { + root.put(cmt.toJSONObject()); + } + + return root.toString(); + } else { + + // Do operator AND + List commentTotal = new LinkedList<>(); + + if (!((postId == null) || postId.isEmpty())) { + List commentListResult = new LinkedList<>(); + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + int postIdInt = Integer.parseInt(postId); + + if (comment.getPostId() == postIdInt) + commentListResult.add(comment); + } + + // Find out union result save to commentSetTotal + if (commentTotal.isEmpty()) { + commentTotal.addAll(commentListResult); + } else { + List commentTotalNew = new LinkedList<>(); + + for(int a = 0; a < commentTotal.size(); a++) { + Comment cmt1 = commentTotal.get(a); + + for(int b = 0; b < commentListResult.size(); b++) { + Comment cmt2 = commentListResult.get(b); + + if (cmt1 == cmt2) + commentTotalNew.add(cmt2); + } + } + + commentTotal = commentTotalNew; + } + } + + if (!((commentId == null) || commentId.isEmpty())) { + List commentListResult = new LinkedList<>(); + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + int commentIdInt = Integer.parseInt(commentId); + + if (comment.getId() == commentIdInt) + commentListResult.add(comment); + } + + // Find out union result save to commentSetTotal + if (commentTotal.isEmpty()) { + commentTotal.addAll(commentListResult); + } else { + List commentTotalNew = new LinkedList<>(); + + for(int a = 0; a < commentTotal.size(); a++) { + Comment cmt1 = commentTotal.get(a); + + for(int b = 0; b < commentListResult.size(); b++) { + Comment cmt2 = commentListResult.get(b); + + if (cmt1 == cmt2) + commentTotalNew.add(cmt2); + } + } + + commentTotal = commentTotalNew; + } + } + + if (!((name == null) || name.isEmpty())) { + List commentListResult = new LinkedList<>(); + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getName().contains(name)) + commentListResult.add(comment); + } + + // Find out union result save to commentSetTotal + if (commentTotal.isEmpty()) { + commentTotal.addAll(commentListResult); + } else { + List commentTotalNew = new LinkedList<>(); + + for(int a = 0; a < commentTotal.size(); a++) { + Comment cmt1 = commentTotal.get(a); + + for(int b = 0; b < commentListResult.size(); b++) { + Comment cmt2 = commentListResult.get(b); + + if (cmt1 == cmt2) + commentTotalNew.add(cmt2); + } + } + + commentTotal = commentTotalNew; + } + } + + if (!((email == null) || email.isEmpty())) { + List commentListResult = new LinkedList<>(); + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getEmail().contains(email)) + commentListResult.add(comment); + } + + // Find out union result save to commentSetTotal + if (commentTotal.isEmpty()) { + commentTotal.addAll(commentListResult); + } else { + List commentTotalNew = new LinkedList<>(); + + for(int a = 0; a < commentTotal.size(); a++) { + Comment cmt1 = commentTotal.get(a); + + for(int b = 0; b < commentListResult.size(); b++) { + Comment cmt2 = commentListResult.get(b); + + if (cmt1 == cmt2) + commentTotalNew.add(cmt2); + } + } + + commentTotal = commentTotalNew; + } + } + + if (!((body == null) || body.isEmpty())) { + List commentListResult = new LinkedList<>(); + + // Remove unrelated post id + for(int a = 0; a < commentList.size(); a++) { + Comment comment = commentList.get(a); + + if (comment.getBody().contains(body)) + commentListResult.add(comment); + } + + // Find out union result save to commentSetTotal + if (commentTotal.isEmpty()) { + commentTotal.addAll(commentListResult); + } else { + List commentTotalNew = new LinkedList<>(); + + for(int a = 0; a < commentTotal.size(); a++) { + Comment cmt1 = commentTotal.get(a); + + for(int b = 0; b < commentListResult.size(); b++) { + Comment cmt2 = commentListResult.get(b); + + if (cmt1 == cmt2) + commentTotalNew.add(cmt2); + } + } + + commentTotal = commentTotalNew; + } + } + + // Response JSONArray + JSONArray root = new JSONArray(); + + for(Comment cmt : commentTotal) { + root.put(cmt.toJSONObject()); + } + + return root.toString(); + } + } +} + +//~ v2, 2020-10-02 03:53:15PM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/controller/TestController.java b/src/main/java/com/hoelee/demo/demo/controller/TestController.java new file mode 100644 index 0000000..86e7a34 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/controller/TestController.java @@ -0,0 +1,84 @@ +package com.hoelee.demo.demo.controller; + +import com.hoelee.demo.demo.entity.Comment; +import com.hoelee.demo.demo.entity.Post; +import com.hoelee.demo.demo.helper.InternetHelper; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import org.json.JSONArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/test", method = {RequestMethod.GET, RequestMethod.POST}) +public class TestController { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + // + @Autowired + private InternetHelper internetHelper; + + @ResponseBody + @GetMapping({"/1"}) + private String testSorting() { + List commentList = internetHelper.readAllComments(); + List postList = new LinkedList<>(); + Post post1 = new Post(); + List commentList1 = new LinkedList<>(); + + commentList1.add(new Comment()); + commentList1.add(new Comment()); + commentList1.add(new Comment()); + post1.setCommentList(commentList1); + + Post post2 = new Post(); + List commentList2 = new LinkedList<>(); + + commentList2.add(new Comment()); + commentList2.add(new Comment()); + post2.setCommentList(commentList2); + + Post post3 = new Post(); + List commentList3 = new LinkedList<>(); + + commentList3.add(new Comment()); + post3.setCommentList(commentList3); + postList.add(post1); + postList.add(post2); + postList.add(post3); + Collections.sort(postList, + new Comparator() { + + @Override + public int compare(Post post1, Post post2) { + int post1CommentSize = post1.getCommentList().size(); + int post2CommentSize = post2.getCommentList().size(); + + return post2CommentSize - post1CommentSize; + } + + }); + + JSONArray root = new JSONArray(); + + for(int a = 0; a < postList.size(); a++) { + root.put(postList.get(a).toJSONObjectCustomResponse1()); + } + + return root.toString(); + } + + @GetMapping("/2") + private String testThymeleaf() { + return "testing.html"; + } +} diff --git a/src/main/java/com/hoelee/demo/demo/entity/Comment.java b/src/main/java/com/hoelee/demo/demo/entity/Comment.java new file mode 100644 index 0000000..c8ba4f9 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/entity/Comment.java @@ -0,0 +1,105 @@ +package com.hoelee.demo.demo.entity; + +import com.hoelee.demo.demo.exception.ExceptionJSONConversion; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

Class desc:

+ * + * + * @version v2, 2020-10-01 06:30:52PM + * @author hoelee + */ +public class Comment { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private int postId; + private int id; + private String name; + private String email; + private String body; + + public Comment(){ + } + + public Comment(int postId, int id, String name, String email, String body) { + this.postId = postId; + this.id = id; + this.name = name; + this.email = email; + this.body = body; + } + + public int getPostId() { + return postId; + } + + public void setPostId(int postId) { + this.postId = postId; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public void fromJSONObject(JSONObject jo) throws Exception{ + try{ + if(jo.has("postId")) + postId = jo.getInt("postId"); + if (jo.has("id")) + id = jo.getInt("id"); + if (jo.has("name")) + name = jo.getString("name"); + if (jo.has("email")) + email = jo.getString("email"); + if (jo.has("body")) + body = jo.getString("body"); + }catch(Exception ex){ + log.error(ex.getLocalizedMessage()); + throw new ExceptionJSONConversion(ex.getLocalizedMessage()); + } + } + + public JSONObject toJSONObject(){ + JSONObject jo = new JSONObject(); + jo.put("postId", postId); + jo.put("id", id); + jo.put("name", name); + jo.put("email", email); + jo.put("body", body); + return jo; + } + +} + +//~ v2, 2020-10-01 06:30:52PM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/entity/Post.java b/src/main/java/com/hoelee/demo/demo/entity/Post.java new file mode 100644 index 0000000..3c59321 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/entity/Post.java @@ -0,0 +1,199 @@ +package com.hoelee.demo.demo.entity; + +import com.hoelee.demo.demo.exception.ExceptionJSONConversion; + +import org.json.JSONObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.LinkedList; +import java.util.List; + +/** + *

Class desc:

+ * + * + * @version v2, 2020-10-02 11:47:11AM + * @author hoelee + */ +public class Post { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + // All the comments for this post + private List commentList = new LinkedList<>(); + private int userId; + private int id; + private String title; + private String body; + + /** hoelee v2 2020-10-02 11:47:11AM + *

Constructor desc:

+ * + */ + public Post() {} + + /** hoelee v2 2020-10-02 11:47:11AM + *

Constructor desc:

+ * + * + * @param userId + * @param id + * @param title + * @param body + */ + public Post(int userId, int id, String title, String body) { + this.userId = userId; + this.id = id; + this.title = title; + this.body = body; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * @return + */ + public int getUserId() { + return userId; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * + * @param userId + */ + public void setUserId(int userId) { + this.userId = userId; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * @return + */ + public int getId() { + return id; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * + * @param id + */ + public void setId(int id) { + this.id = id; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * @return + */ + public String getTitle() { + return title; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * + * @param title + */ + public void setTitle(String title) { + this.title = title; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * @return + */ + public String getBody() { + return body; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * + * @param body + */ + public void setBody(String body) { + this.body = body; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * All the comments for this post + * + * @return + */ + public List getCommentList() { + return commentList; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * All the comments for this post + * + * @param commentList + */ + public void setCommentList(List commentList) { + this.commentList = commentList; + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * + * @param jo + * + * @throws Exception + */ + public void fromJSONObject(JSONObject jo) throws Exception { + try { + if (jo.has("userId")) + userId = jo.getInt("userId"); + if (jo.has("id")) + id = jo.getInt("id"); + if (jo.has("title")) + title = jo.getString("title"); + if (jo.has("body")) + body = jo.getString("body"); + } catch (Exception ex) { + log.error(ex.getLocalizedMessage()); + throw new ExceptionJSONConversion(ex.getLocalizedMessage()); + } + } + + /** hoelee v2 2020-10-02 11:47:11AM + *

Method desc:

+ * + * @return + */ + public JSONObject toJSONObject() { + JSONObject jo = new JSONObject(); + + jo.put("userId", userId); + jo.put("id", id); + jo.put("title", title); + jo.put("body", body); + return jo; + } + + public JSONObject toJSONObjectCustomResponse1(){ + JSONObject jo = new JSONObject(); + + jo.put("post_id", id); + jo.put("post_title", title); + jo.put("post_body", body); + jo.put("total_number_of_comments", commentList.size()); + return jo; + } + +} + +//~ v2, 2020-10-02 11:47:11AM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/exception/ExceptionJSONConversion.java b/src/main/java/com/hoelee/demo/demo/exception/ExceptionJSONConversion.java new file mode 100644 index 0000000..8d9424b --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/exception/ExceptionJSONConversion.java @@ -0,0 +1,36 @@ +package com.hoelee.demo.demo.exception; + +/** + *

Class desc:

+ * Handle own JSONObject & JSONArray convert to object + * + * @version v2, 2020-10-01 06:39:32PM + * @author hoelee + */ +public class ExceptionJSONConversion extends Exception { + + private Class modelClass; + + /** hoelee v2 2020-10-01 06:39:32PM + *

Constructor desc:

+ * + * + * @param message + */ + public ExceptionJSONConversion(String message) { + super(message); + + this.modelClass = modelClass; + } + + /** hoelee v2 2020-10-01 06:39:32PM + *

Method desc:

+ * + * @return + */ + public Class getModelClass() { + return modelClass; + } +} + +//~ v2, 2020-10-01 06:39:32PM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/helper/InternetHelper.java b/src/main/java/com/hoelee/demo/demo/helper/InternetHelper.java new file mode 100644 index 0000000..47b9c2f --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/helper/InternetHelper.java @@ -0,0 +1,222 @@ +package com.hoelee.demo.demo.helper; + +import com.hoelee.demo.demo.entity.Comment; +import com.hoelee.demo.demo.entity.Post; + +import okhttp3.Call; +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import org.json.JSONArray; +import org.json.JSONObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.servlet.http.HttpServletRequest; + +/** + *

Class desc:

+ * + * + * @version v2, 2020-09-30 03:14:36AM + * @author hoelee + */ +@Component +public class InternetHelper { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private HttpServletRequest request; + + /** hoelee v2 2020-10-01 06:10:46PM + *

Method desc:

+ * + * + * @param request + */ + @Autowired + public void setRequest(HttpServletRequest request) { + this.request = request; + } + + /** hoelee v2 2020-10-01 06:10:46PM + *

Method desc:

+ * + * @return + */ + public List readAllComments() { + String epReadComments = "https://jsonplaceholder.typicode.com/comments"; + String response = synchronizeRequestGetMethod(epReadComments); + + try { + JSONArray ja = new JSONArray(response); + List commentList = new LinkedList<>(); + + for(int a = 0; a < ja.length(); a++) { + JSONObject jo = ja.getJSONObject(a); + Comment comment = new Comment(); + + comment.fromJSONObject(jo); + commentList.add(comment); + } + + return commentList; + } catch (Exception ex) { + log.error(ex.getLocalizedMessage()); + return null; + } + } + + /** hoelee v2 2020-10-01 06:10:46PM + *

Method desc:

+ * + * @return + */ + public List readAllPosts() { + String epReadPosts = "https://jsonplaceholder.typicode.com/posts"; + String response = synchronizeRequestGetMethod(epReadPosts); + + try { + JSONArray ja = new JSONArray(response); + List postList = new LinkedList<>(); + + for(int a = 0; a < ja.length(); a++) { + JSONObject jo = ja.getJSONObject(a); + Post post = new Post(); + + post.fromJSONObject(jo); + postList.add(post); + } + + return postList; + } catch (Exception ex) { + log.error(ex.getLocalizedMessage()); + return null; + } + } + + /** hoelee v2 2020-10-01 06:10:46PM + *

Method desc:

+ * + * + * @param postId + * @return + */ + public Post readPostById(int postId) { + String epReadPost = "https://jsonplaceholder.typicode.com/posts/" + postId; + String response = synchronizeRequestGetMethod(epReadPost); + + try { + JSONObject jo = null; + Post post = new Post(); + + jo = new JSONObject(response); + + post.fromJSONObject(jo); + return post; + } catch (Exception ex) { + log.error(ex.getLocalizedMessage()); + return null; + } + } + + /** hoelee v2 2020-10-01 06:10:46PM + *

Method desc:

+ * + * + * @param commentId + * @return + */ + public Comment readCommentById(int commentId) { + String epReadComment = "https://jsonplaceholder.typicode.com/comments/" + commentId; + String response = synchronizeRequestGetMethod(epReadComment); + + try { + JSONObject jo = new JSONObject(response); + Comment comment = new Comment(); + + comment.fromJSONObject(jo); + return comment; + } catch (Exception ex) { + log.error(ex.getLocalizedMessage()); + return null; + } + } + + /** hoelee v2 2020-09-30 03:14:36AM + *

Method desc:

+ * + * + * @param url + * @return + */ + private String synchronizeRequestGetMethod(String url) { + CookieJar cookieJar = new CookieJar() { + + @Override + public void saveFromResponse(HttpUrl url, List cookies) { + + // Save Cookies + String urlString = url.toString(); + + for(Cookie cookie : cookies) { + String cookieString = cookie.toString(); + } + } + @Override + public List loadForRequest(HttpUrl url) { + + // Load new cookies + ArrayList cookies = new ArrayList<>(); + Cookie cookie = new Cookie.Builder().hostOnlyDomain(url.host()).name("key").value("value").build(); + + cookies.add(cookie); + return cookies; + } + }; + HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); + + // Add Parameters + //urlBuilder.addQueryParameter("key", "value"); + String finalUrl = urlBuilder.build().toString(); + OkHttpClient mOkHttpClient = new OkHttpClient.Builder() // + .connectTimeout(60, TimeUnit.SECONDS).cookieJar(cookieJar).build(); + Request request = new Request.Builder().url(finalUrl).build(); + Call call = mOkHttpClient.newCall(request); + Response response = null; + String body = null; + + try { + response = call.execute(); + + if (response.isSuccessful()) + body = response.body().string(); + else + log.warn("Http Get Request not success with URL: " + url); + } catch (IOException e) { + log.error("Http GET Request failed with URL: " + url + " because of " + e.getLocalizedMessage()); + } finally { + try { + response.close(); + } catch (Exception ex) {} + } + + return body; + } +} + +//~ v2, 2020-10-02 11:37:44AM - Last edited by hoelee diff --git a/src/main/java/com/hoelee/demo/demo/helper/ListHelper.java b/src/main/java/com/hoelee/demo/demo/helper/ListHelper.java new file mode 100644 index 0000000..f8c5867 --- /dev/null +++ b/src/main/java/com/hoelee/demo/demo/helper/ListHelper.java @@ -0,0 +1,56 @@ +package com.hoelee.demo.demo.helper; + +import com.hoelee.demo.demo.entity.Comment; + +import java.util.LinkedList; +import java.util.List; + +/** + *

+ * Class desc:

+ * + * @version v2, 2020-10-02 02:48:54PM + * @author hoelee + */ +public class ListHelper { + + /** + * hoelee v2 2020-10-02 02:48:54PM + *

+ * Method desc:

+ * Search same Comment in give 2 Comment LinkedList + * + * @param l1 + * @param l2 + * @return + */ + public static List findSameCommentInList(List l1, List l2) { + // If l2 empty no need find + if (l2.isEmpty()) + return l1; + + List result = new LinkedList<>(); + + for (int a = 0; a < l1.size(); a++) { + Comment l1Obj = (Comment) l1.get(a); + boolean gotSame = false; + + for (int b = 0; b < l2.size(); b++) { + Comment l2Obj = (Comment) l2.get(b); + + if (l1Obj == l2Obj) { + gotSame = true; + break; + } + } + + if (gotSame) { + result.add(l1Obj); + } + } + + return result; + } +} + +//~ v2, 2020-10-02 02:48:54PM - Last edited by hoelee diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..a755768 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,10 @@ +spring.server.port=10080 + + + + + + + + diff --git a/src/main/resources/rebel.xml b/src/main/resources/rebel.xml new file mode 100644 index 0000000..dfe6fa3 --- /dev/null +++ b/src/main/resources/rebel.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/templates/testing.html b/src/main/resources/templates/testing.html new file mode 100644 index 0000000..c627c24 --- /dev/null +++ b/src/main/resources/templates/testing.html @@ -0,0 +1,16 @@ + + + + + TODO supply a title + + + + +
TODO write content
+ + diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000..fd2fac1 --- /dev/null +++ b/src/main/webapp/META-INF/context.xml @@ -0,0 +1,2 @@ + + diff --git a/src/main/webapp/WEB-INF/thymeleaf/testing.html b/src/main/webapp/WEB-INF/thymeleaf/testing.html new file mode 100644 index 0000000..c627c24 --- /dev/null +++ b/src/main/webapp/WEB-INF/thymeleaf/testing.html @@ -0,0 +1,16 @@ + + + + + TODO supply a title + + + + +
TODO write content
+ + diff --git a/src/test/java/com/hoelele/demo/demo/DemoApplicationTests.java b/src/test/java/com/hoelee/demo/demo/DemoApplicationTests.java similarity index 54% rename from src/test/java/com/hoelele/demo/demo/DemoApplicationTests.java rename to src/test/java/com/hoelee/demo/demo/DemoApplicationTests.java index 1b75cc7..845fdb4 100644 --- a/src/test/java/com/hoelele/demo/demo/DemoApplicationTests.java +++ b/src/test/java/com/hoelee/demo/demo/DemoApplicationTests.java @@ -1,13 +1,14 @@ -package com.hoelele.demo.demo; +package com.hoelee.demo.demo; import org.junit.jupiter.api.Test; + import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class DemoApplicationTests { - @Test - void contextLoads() { - } - + @Test + void contextLoads() {} } + +//~ v2, 2020-09-30 12:23:32AM - Last edited by hoelee