= ChuckNorris = * Test app that invokes a ChuckNorris random joke API == Structure == {{{#!highlight bash . ├── pom.xml ├── src │ └── main │ └── java │ ├── chucknorris │ │ └── bitarus │ │ └── allowed │ │ └── org │ │ ├── Application.java │ │ ├── ChuckNorrisController.java │ │ ├── Joke.java │ │ └── JokeResponse.java }}} === pom.xml === {{{#!highlight xml 4.0.0 bitarus.allowed.org chucknorris 0.1.0 org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web com.google.code.gson gson 2.8.6 compile chucknorris.bitarus.allowed.org.Application org.springframework.boot spring-boot-maven-plugin spring-milestone http://repo.spring.io/libs-release spring-milestone http://repo.spring.io/libs-release }}} === Application.java === {{{#!highlight java package chucknorris.bitarus.allowed.org; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ComponentScan //scans for @Component beans @EnableAutoConfiguration public class Application { private static Logger logger; public static void main(String[] args) { logger = LoggerFactory.getLogger(Application.class); logger.info("Starting application"); SpringApplication.run(Application.class, args); } } }}} === ChuckNorrisController.java === {{{#!highlight java package chucknorris.bitarus.allowed.org; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.ui.Model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ResponseBody; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import org.springframework.http.HttpMethod; import com.google.gson.Gson; import java.util.stream.Stream; import java.util.stream.Collectors; import java.util.List; import java.util.ArrayList; @Controller public class ChuckNorrisController{ private final Logger logger = LoggerFactory.getLogger(ChuckNorrisController.class); public ChuckNorrisController(){ logger.info("ChuckNorrisController created"); } @RequestMapping("/chucknorris") @ResponseBody // http://localhost:8080/chucknorris public JokeResponse chucknorris() { String ret = ""; Gson gson = new Gson(); try { URL url = new URL("https://api.chucknorris.io/jokes/random"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); logger.info( Integer.toString(connection.getResponseCode() )); try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) { StringBuilder response = new StringBuilder(); String responseLine = null; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } Joke joke = gson.fromJson(response.toString(), Joke.class); List jokesList = new ArrayList(); jokesList.add(joke); List jokesList2 = jokesList.stream().map( item ->{item.setValue(item.getValue().toUpperCase()); return item;} ).collect(Collectors.toList()); joke = jokesList2.get(0); ret = joke.getValue(); } } catch(Exception ex){ logger.error("error",ex); } JokeResponse jr = new JokeResponse(); jr.setResponse(ret); return jr; } } }}} === Joke.java === {{{#!highlight java package chucknorris.bitarus.allowed.org; import com.google.gson.annotations.SerializedName; public class Joke{ @SerializedName("categories") private String[] categories; @SerializedName("created_at") private String createdAt; @SerializedName("icon_url") private String iconUrl; @SerializedName("id") private String id; @SerializedName("updated_at") private String updatedAt; @SerializedName("url") private String url; @SerializedName("value") private String value; public String[] getCategories(){ return this.categories; } public String getCreatedAt(){ return this.createdAt; } public String getIconUrl(){ return this.iconUrl; } public String getId(){ return this.id; } public String getUpdatedAt(){ return this.updatedAt; } public String getUrl(){ return this.url; } public String getValue(){ return this.value; } public void setCategories(String[] categories){ this.categories = categories; } public void setCreatedAt(String createdAt ){ this.createdAt = createdAt; } public void setIconUrl(String iconUrl){ this.iconUrl=iconUrl; } public void setId(String id){ this.id=id; } public void setUpdatedAt(String updatedAt){ this.updatedAt=updatedAt; } public void setUrl(String url){ this.url=url; } public void setValue(String value){ this.value=value; } } }}} === JokeResponse.java === {{{#!highlight java package chucknorris.bitarus.allowed.org; import com.google.gson.annotations.SerializedName; public class JokeResponse{ @SerializedName("response") private String response; public String getResponse(){ return this.response; } public void setResponse(String response){ this.response = response; } } }}} == curl call == {{{#!highlight bash curl https://api.chucknorris.io/jokes/random 2>/dev/null | json_reformat { "categories": [ ], "created_at": "2020-01-05 13:42:26.991637", "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png", "id": "H-fvHao6QmiQxunoX2llBg", "updated_at": "2020-01-05 13:42:26.991637", "url": "https://api.chucknorris.io/jokes/H-fvHao6QmiQxunoX2llBg", "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." } }}} == Example 0.2 == === Structure === {{{#!highlight sh . ├── pom.xml ├── src │   └── main │   ├── java │   │   └── com │   │   └── mooo │   │   └── bitarus │   │   └── chucknorris │   │   ├── Application.java │   │   ├── ChuckNorrisController.java │   │   ├── JokeEntity.java │   │   ├── Joke.java │   │   ├── JokeMapper.java │   │   ├── JokeProjection.java │   │   ├── JokeRepository.java │   │   ├── JokeResponse.java │   │   └── QueryDSLConfiguration.java │   └── resources │   └── application.yaml }}} === pom.xml === {{{#!highlight xml 4.0.0 com.mooo.bitarus chucknorris 0.2.0 org.springframework.boot spring-boot-starter-parent 3.2.5 org.mapstruct mapstruct ${mapstruct.version} org.springdoc springdoc-openapi-starter-webmvc-ui 2.5.0 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.hsqldb hsqldb 2.7.2 com.querydsl querydsl-jpa ${querydsl.version} jakarta com.querydsl querydsl-apt ${querydsl.version} jakarta 21 com.mooo.bitarus.chucknorris.Application 5.1.0 1.5.5.Final org.springframework.boot spring-boot-maven-plugin org.apache.maven.plugins maven-compiler-plugin 3.11.0 org.mapstruct mapstruct-processor ${mapstruct.version} com.querydsl querydsl-apt ${querydsl.version} jakarta jakarta.persistence jakarta.persistence-api 3.1.0 spring-milestone http://repo.spring.io/libs-release spring-milestone http://repo.spring.io/libs-release }}}