MoinMoin Logo
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Navigation

  • Start
  • Sitemap

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Revision 8 as of 2024-05-12 12:22:29
  • Java
  • Spring
  • SpringBoot
  • ChuckNorris

ChuckNorris

  • Test app that invokes a ChuckNorris random joke API

Structure

   1 .
   2 ├── pom.xml
   3 ├── src
   4 │   └── main
   5 │       └── java
   6 │           ├── chucknorris
   7 │           │   └── bitarus
   8 │           │       └── allowed
   9 │           │           └── org
  10 │           │               ├── Application.java
  11 │           │               ├── ChuckNorrisController.java
  12 │           │               ├── Joke.java
  13 │           │               └── JokeResponse.java

pom.xml

   1 <?xml version="1.0" encoding="UTF-8"?>
   2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   3     <modelVersion>4.0.0</modelVersion>
   4     <groupId>bitarus.allowed.org</groupId>
   5     <artifactId>chucknorris</artifactId>
   6     <version>0.1.0</version>
   7     <parent>
   8         <groupId>org.springframework.boot</groupId>
   9         <artifactId>spring-boot-starter-parent</artifactId>
  10         <version>2.1.6.RELEASE</version>
  11     </parent>
  12     <dependencies>
  13         <dependency>
  14             <groupId>org.springframework.boot</groupId>
  15             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  16         </dependency>
  17         <dependency>
  18             <groupId>org.springframework.boot</groupId>
  19             <artifactId>spring-boot-starter-web</artifactId>
  20         </dependency>
  21         <dependency>
  22             <groupId>com.google.code.gson</groupId>
  23             <artifactId>gson</artifactId>
  24             <version>2.8.6</version>
  25             <scope>compile</scope>
  26         </dependency>
  27     </dependencies>
  28     <properties>
  29         <start-class>chucknorris.bitarus.allowed.org.Application</start-class>
  30     </properties>
  31     <build>
  32         <plugins>
  33             <plugin>
  34                 <groupId>org.springframework.boot</groupId>
  35                 <artifactId>spring-boot-maven-plugin</artifactId>
  36             </plugin>
  37         </plugins>
  38     </build>
  39     <repositories>
  40         <repository>
  41             <id>spring-milestone</id>
  42             <url>http://repo.spring.io/libs-release</url>
  43         </repository>
  44     </repositories>
  45     <pluginRepositories>
  46         <pluginRepository>
  47             <id>spring-milestone</id>
  48             <url>http://repo.spring.io/libs-release</url>
  49         </pluginRepository>
  50     </pluginRepositories>
  51 </project>

Application.java

   1 package chucknorris.bitarus.allowed.org;
   2 
   3 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
   4 import org.springframework.boot.SpringApplication;
   5 import org.springframework.context.annotation.ComponentScan;
   6 import org.slf4j.Logger;
   7 import org.slf4j.LoggerFactory;
   8 
   9 @ComponentScan //scans for @Component beans 
  10 @EnableAutoConfiguration
  11 public class Application {
  12     private static Logger logger;
  13 
  14     public static void main(String[] args) {
  15         logger = LoggerFactory.getLogger(Application.class);
  16         logger.info("Starting application");
  17         SpringApplication.run(Application.class, args);
  18     }
  19 }

ChuckNorrisController.java

   1 package chucknorris.bitarus.allowed.org;
   2 
   3 import org.springframework.stereotype.Controller;
   4 import org.springframework.web.bind.annotation.RequestMapping;
   5 import org.springframework.ui.Model;
   6 import org.slf4j.Logger;
   7 import org.slf4j.LoggerFactory;
   8 import org.springframework.web.bind.annotation.ResponseBody;
   9 
  10 import java.io.BufferedReader;
  11 import java.io.InputStreamReader;
  12 import java.io.OutputStream;
  13 import java.net.HttpURLConnection;
  14 import java.net.URL;
  15 import org.springframework.http.HttpMethod;
  16 import com.google.gson.Gson;
  17 import java.util.stream.Stream;
  18 import java.util.stream.Collectors;
  19 import java.util.List;
  20 import java.util.ArrayList;
  21 
  22 @Controller
  23 public class ChuckNorrisController{
  24     private final Logger logger = LoggerFactory.getLogger(ChuckNorrisController.class);
  25     
  26     public ChuckNorrisController(){
  27         logger.info("ChuckNorrisController created");
  28     }
  29 
  30     @RequestMapping("/chucknorris")
  31     @ResponseBody
  32     // http://localhost:8080/chucknorris
  33     public JokeResponse chucknorris() {
  34         String ret = "";
  35         Gson gson = new Gson();
  36 
  37         try {
  38             URL url = new URL("https://api.chucknorris.io/jokes/random");
  39             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  40             connection.connect();
  41             logger.info( Integer.toString(connection.getResponseCode() ));
  42 
  43             try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
  44                 StringBuilder response = new StringBuilder();
  45                 String responseLine = null;
  46                 while ((responseLine = br.readLine()) != null) {
  47                     response.append(responseLine.trim());
  48                 }
  49                 
  50                 Joke joke = gson.fromJson(response.toString(), Joke.class);
  51                 
  52 
  53                 List<Joke> jokesList = new ArrayList<Joke>();
  54                 jokesList.add(joke);
  55                 List<Joke> jokesList2 = jokesList.stream().map( item ->{item.setValue(item.getValue().toUpperCase()); return item;} ).collect(Collectors.toList());
  56                 joke = jokesList2.get(0);
  57                 ret = joke.getValue();
  58             }
  59 
  60         }
  61         catch(Exception ex){
  62             logger.error("error",ex);
  63         }
  64 
  65         JokeResponse jr = new JokeResponse();
  66         jr.setResponse(ret);
  67         return jr;
  68     }
  69 }

Joke.java

   1 package chucknorris.bitarus.allowed.org;
   2 import com.google.gson.annotations.SerializedName;
   3 
   4 public class Joke{
   5  
   6     @SerializedName("categories")
   7     private String[] categories;
   8     @SerializedName("created_at")
   9     private String createdAt;
  10     @SerializedName("icon_url")
  11     private String iconUrl;
  12     @SerializedName("id")
  13     private String id;
  14     @SerializedName("updated_at")
  15     private String updatedAt;
  16     @SerializedName("url")
  17     private String url;
  18     @SerializedName("value")
  19     private String value;    
  20 
  21     public String[] getCategories(){
  22         return this.categories;
  23     }
  24 
  25     public String getCreatedAt(){        
  26         return this.createdAt;
  27     }
  28 
  29     public String getIconUrl(){
  30         return this.iconUrl;        
  31     }
  32 
  33     public String getId(){   
  34         return this.id;     
  35     }
  36 
  37     public String getUpdatedAt(){        
  38         return this.updatedAt;
  39     }
  40 
  41     public String getUrl(){    
  42         return this.url;    
  43     }
  44 
  45     public String getValue(){
  46         return this.value;
  47     }
  48 
  49     public void setCategories(String[] categories){
  50         this.categories = categories;
  51     }
  52 
  53     public void setCreatedAt(String createdAt ){        
  54         this.createdAt = createdAt;
  55     }
  56 
  57     public void setIconUrl(String iconUrl){
  58         this.iconUrl=iconUrl;        
  59     }
  60 
  61     public void setId(String id){   
  62         this.id=id;     
  63     }
  64 
  65     public void setUpdatedAt(String updatedAt){        
  66         this.updatedAt=updatedAt;
  67     }
  68 
  69     public void setUrl(String url){    
  70         this.url=url;    
  71     }
  72 
  73     public void setValue(String value){
  74         this.value=value;
  75     }
  76 }

JokeResponse.java

   1 package chucknorris.bitarus.allowed.org;
   2 import com.google.gson.annotations.SerializedName;
   3 
   4 public class JokeResponse{
   5  
   6     @SerializedName("response")
   7     private String response;    
   8 
   9     public String getResponse(){
  10         return this.response;
  11     }
  12 
  13     public void setResponse(String response){
  14         this.response = response;
  15     }
  16 }

curl call

   1 curl https://api.chucknorris.io/jokes/random 2>/dev/null | json_reformat 
   2 {
   3     "categories": [
   4 
   5     ],
   6     "created_at": "2020-01-05 13:42:26.991637",
   7     "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
   8     "id": "H-fvHao6QmiQxunoX2llBg",
   9     "updated_at": "2020-01-05 13:42:26.991637",
  10     "url": "https://api.chucknorris.io/jokes/H-fvHao6QmiQxunoX2llBg",
  11     "value": "A doctor once tried to test Chuck Norris' reflexes by lightly tapping on his knee with a small wooden mallet. Needless to say, that doctor is now in orbit."
  12 }

== Example 0.2 ==

Structure

   1 .
   2 ├── pom.xml
   3 ├── src
   4 │   └── main
   5 │       ├── java
   6 │       │   └── com
   7 │       │       └── mooo
   8 │       │           └── bitarus
   9 │       │               └── chucknorris
  10 │       │                   ├── Application.java
  11 │       │                   ├── ChuckNorrisController.java
  12 │       │                   ├── JokeEntity.java
  13 │       │                   ├── Joke.java
  14 │       │                   ├── JokeMapper.java
  15 │       │                   ├── JokeProjection.java
  16 │       │                   ├── JokeRepository.java
  17 │       │                   ├── JokeResponse.java
  18 │       │                   └── QueryDSLConfiguration.java
  19 │       └── resources
  20 │           └── application.yaml

pom.xml

   1 <?xml version="1.0" encoding="UTF-8"?>
   2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   3     <modelVersion>4.0.0</modelVersion>
   4     <groupId>com.mooo.bitarus</groupId>
   5     <artifactId>chucknorris</artifactId>
   6     <version>0.2.0</version>
   7     <parent>
   8         <groupId>org.springframework.boot</groupId>
   9         <artifactId>spring-boot-starter-parent</artifactId>
  10         <version>3.2.5</version>
  11     </parent>
  12     <dependencies>
  13         <dependency>
  14             <groupId>org.mapstruct</groupId>
  15             <artifactId>mapstruct</artifactId>
  16             <version>${mapstruct.version}</version>
  17         </dependency>
  18         <dependency>
  19             <groupId>org.springdoc</groupId>
  20             <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  21             <version>2.5.0</version>
  22         </dependency>
  23         <dependency>
  24             <groupId>org.springframework.boot</groupId>
  25             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  26         </dependency>
  27         <dependency>
  28             <groupId>org.springframework.boot</groupId>
  29             <artifactId>spring-boot-starter-web</artifactId>
  30         </dependency>
  31         <dependency>
  32             <groupId>org.springframework.boot</groupId>
  33             <artifactId>spring-boot-starter-data-jpa</artifactId>
  34         </dependency>
  35         <dependency>
  36             <groupId>org.hsqldb</groupId>
  37             <artifactId>hsqldb</artifactId>
  38             <version>2.7.2</version>
  39         </dependency>
  40         <dependency>
  41             <groupId>com.querydsl</groupId>
  42             <artifactId>querydsl-jpa</artifactId>
  43             <version>${querydsl.version}</version>
  44             <classifier>jakarta</classifier>
  45         </dependency>
  46         <dependency>
  47             <groupId>com.querydsl</groupId>
  48             <artifactId>querydsl-apt</artifactId>
  49             <version>${querydsl.version}</version>
  50             <classifier>jakarta</classifier>
  51         </dependency>
  52     </dependencies>
  53     <properties>
  54         <java.version>21</java.version>
  55         <start-class>com.mooo.bitarus.chucknorris.Application</start-class>
  56         <querydsl.version>5.1.0</querydsl.version>
  57         <mapstruct.version>1.5.5.Final</mapstruct.version>
  58     </properties>
  59     <build>
  60         <plugins>
  61             <plugin>
  62                 <groupId>org.springframework.boot</groupId>
  63                 <artifactId>spring-boot-maven-plugin</artifactId>
  64             </plugin>
  65             <plugin>
  66                 <groupId>org.apache.maven.plugins</groupId>
  67                 <artifactId>maven-compiler-plugin</artifactId>
  68                 <version>3.11.0</version>
  69                 <configuration>
  70                     <annotationProcessorPaths>
  71                         <path>
  72                             <groupId>org.mapstruct</groupId>
  73                             <artifactId>mapstruct-processor</artifactId>
  74                             <version>${mapstruct.version}</version>
  75                         </path>
  76                         <path>
  77                             <groupId>com.querydsl</groupId>
  78                             <artifactId>querydsl-apt</artifactId>
  79                             <version>${querydsl.version}</version>
  80                             <classifier>jakarta</classifier>
  81                         </path>
  82                         <path>
  83                             <groupId>jakarta.persistence</groupId>
  84                             <artifactId>jakarta.persistence-api</artifactId>
  85                             <version>3.1.0</version>
  86                         </path>
  87                     </annotationProcessorPaths>
  88                 </configuration>
  89             </plugin>
  90         </plugins>
  91     </build>
  92     <repositories>
  93         <repository>
  94             <id>spring-milestone</id>
  95             <url>http://repo.spring.io/libs-release</url>
  96         </repository>
  97     </repositories>
  98     <pluginRepositories>
  99         <pluginRepository>
 100             <id>spring-milestone</id>
 101             <url>http://repo.spring.io/libs-release</url>
 102         </pluginRepository>
 103     </pluginRepositories>
 104 </project>

src/main/resources/application.yaml

   1 server:
   2   port: 8181
   3 chucknorris:
   4   url: https://api.chucknorris.io/jokes/random
   5 springdoc:
   6   swagger-ui:
   7     enabled: true
   8 # http://localhost:8181/swagger-ui/index.html 
   9 # http://localhost:8181/v3/api-docs.yaml 
  10 # https://docs.swagger.io/swagger-core/v2.0.0-RC3/apidocs/io/swagger/v3/oas/annotations/Operation.html
  11 spring:
  12   datasource:
  13     url: jdbc:hsqldb:mem:mydb
  14     username: sa
  15     password: sa
  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01