Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
2e8ac81c2d
|
@ -0,0 +1,5 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Blade - A Complete GuideBook](http://www.baeldung.com/blade)
|
||||||
|
|
||||||
|
Run Integration Tests with `mvn integration-test`
|
|
@ -0,0 +1,189 @@
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>blade</artifactId>
|
||||||
|
<name>blade</name>
|
||||||
|
|
||||||
|
<!-- WITH THIS mvn integration-test DOES WORK -->
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<!-- WITH THIS mvn integration-test DOESN'T WORK -->
|
||||||
|
<!-- <parent> -->
|
||||||
|
<!-- <groupId>com.baeldung</groupId> -->
|
||||||
|
<!-- <artifactId>parent-modules</artifactId> -->
|
||||||
|
<!-- <version>1.0.0-SNAPSHOT</version> -->
|
||||||
|
<!-- </parent> -->
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bladejava</groupId>
|
||||||
|
<artifactId>blade-mvc</artifactId>
|
||||||
|
<version>2.0.14.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars</groupId>
|
||||||
|
<artifactId>bootstrap</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PROVIDED -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- TEST -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.11.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5.6</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>4.5.6</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
<version>4.4.10</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>sample-blade-app</finalName>
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<forkCount>3</forkCount>
|
||||||
|
<reuseForks>true</reuseForks>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<version>3.0.0-M3</version>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*LiveTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.bazaarvoice.maven.plugins</groupId>
|
||||||
|
<artifactId>process-exec-maven-plugin</artifactId>
|
||||||
|
<version>0.7</version>
|
||||||
|
<executions>
|
||||||
|
<!--Start Blade -->
|
||||||
|
<execution>
|
||||||
|
<id>blade-process</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<name>Blade</name>
|
||||||
|
<waitForInterrupt>false</waitForInterrupt>
|
||||||
|
<arguments>
|
||||||
|
<argument>java</argument>
|
||||||
|
<argument>-jar</argument>
|
||||||
|
<argument>sample-blade-app.jar</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
|
||||||
|
<!--Stop all processes in reverse order -->
|
||||||
|
<execution>
|
||||||
|
<id>stop-all</id>
|
||||||
|
<phase>post-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop-all</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<finalName>${project.build.finalName}</finalName>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.baeldung.blade.sample.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.interceptors.BaeldungMiddleware;
|
||||||
|
import com.blade.Blade;
|
||||||
|
import com.blade.event.EventType;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.http.Session;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Blade.of()
|
||||||
|
.get("/", ctx -> ctx.render("index.html"))
|
||||||
|
.get("/basic-route-example", ctx -> ctx.text("GET called"))
|
||||||
|
.post("/basic-route-example", ctx -> ctx.text("POST called"))
|
||||||
|
.put("/basic-route-example", ctx -> ctx.text("PUT called"))
|
||||||
|
.delete("/basic-route-example", ctx -> ctx.text("DELETE called"))
|
||||||
|
.addStatics("/custom-static")
|
||||||
|
// .showFileList(true)
|
||||||
|
.enableCors(true)
|
||||||
|
.before("/user/*", ctx -> log.info("[NarrowedHook] Before '/user/*', URL called: " + ctx.uri()))
|
||||||
|
.on(EventType.SERVER_STARTED, e -> {
|
||||||
|
String version = WebContext.blade()
|
||||||
|
.env("app.version")
|
||||||
|
.orElse("N/D");
|
||||||
|
log.info("[Event::serverStarted] Loading 'app.version' from configuration, value: " + version);
|
||||||
|
})
|
||||||
|
.on(EventType.SESSION_CREATED, e -> {
|
||||||
|
Session session = (Session) e.attribute("session");
|
||||||
|
session.attribute("mySessionValue", "Baeldung");
|
||||||
|
})
|
||||||
|
.use(new BaeldungMiddleware())
|
||||||
|
.start(App.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.http.Request;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
import com.blade.mvc.http.Session;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class AttributesExampleController {
|
||||||
|
|
||||||
|
public final static String REQUEST_VALUE = "Some Request value";
|
||||||
|
public final static String SESSION_VALUE = "1337";
|
||||||
|
public final static String HEADER = "Some Header";
|
||||||
|
|
||||||
|
@GetRoute("/request-attribute-example")
|
||||||
|
public void getRequestAttribute(Request request, Response response) {
|
||||||
|
request.attribute("request-val", REQUEST_VALUE);
|
||||||
|
String requestVal = request.attribute("request-val");
|
||||||
|
response.text(requestVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/session-attribute-example")
|
||||||
|
public void getSessionAttribute(Request request, Response response) {
|
||||||
|
Session session = request.session();
|
||||||
|
session.attribute("session-val", SESSION_VALUE);
|
||||||
|
String sessionVal = session.attribute("session-val");
|
||||||
|
response.text(sessionVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/header-example")
|
||||||
|
public void getHeader(Request request, Response response) {
|
||||||
|
String headerVal = request.header("a-header", HEADER);
|
||||||
|
response.header("a-header", headerVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.Route;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class LogExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleController.class);
|
||||||
|
|
||||||
|
@Route(value = "/test-logs")
|
||||||
|
public void testLogs(Response response) {
|
||||||
|
log.trace("This is a TRACE Message");
|
||||||
|
log.debug("This is a DEBUG Message");
|
||||||
|
log.info("This is an INFO Message");
|
||||||
|
log.warn("This is a WARN Message");
|
||||||
|
log.error("This is an ERROR Message");
|
||||||
|
response.text("Check in ./logs");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.vo.User;
|
||||||
|
import com.blade.mvc.annotation.CookieParam;
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.HeaderParam;
|
||||||
|
import com.blade.mvc.annotation.JSON;
|
||||||
|
import com.blade.mvc.annotation.MultipartParam;
|
||||||
|
import com.blade.mvc.annotation.Param;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.PathParam;
|
||||||
|
import com.blade.mvc.annotation.PostRoute;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
import com.blade.mvc.multipart.FileItem;
|
||||||
|
import com.blade.mvc.ui.RestResponse;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class ParameterInjectionExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ParameterInjectionExampleController.class);
|
||||||
|
|
||||||
|
@GetRoute("/params/form")
|
||||||
|
public void formParam(@Param String name, Response response) {
|
||||||
|
log.info("name: " + name);
|
||||||
|
response.text(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/path/:uid")
|
||||||
|
public void restfulParam(@PathParam Integer uid, Response response) {
|
||||||
|
log.info("uid: " + uid);
|
||||||
|
response.text(String.valueOf(uid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/params-file") // DO NOT USE A SLASH WITHIN THE ROUTE OR IT WILL BREAK (?)
|
||||||
|
@JSON
|
||||||
|
public RestResponse<?> fileParam(@MultipartParam FileItem fileItem) throws Exception {
|
||||||
|
try {
|
||||||
|
byte[] fileContent = fileItem.getData();
|
||||||
|
|
||||||
|
log.debug("Saving the uploaded file");
|
||||||
|
java.nio.file.Path tempFile = Files.createTempFile("baeldung_tempfiles", ".tmp");
|
||||||
|
Files.write(tempFile, fileContent, StandardOpenOption.WRITE);
|
||||||
|
|
||||||
|
return RestResponse.ok();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return RestResponse.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/header")
|
||||||
|
public void headerParam(@HeaderParam String customheader, Response response) {
|
||||||
|
log.info("Custom header: " + customheader);
|
||||||
|
response.text(customheader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/cookie")
|
||||||
|
public void cookieParam(@CookieParam(defaultValue = "default value") String myCookie, Response response) {
|
||||||
|
log.info("myCookie: " + myCookie);
|
||||||
|
response.text(myCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/params/vo")
|
||||||
|
public void voParam(@Param User user, Response response) {
|
||||||
|
log.info("user as voParam: " + user.toString());
|
||||||
|
response.html(user.toString() + "<br/><br/><a href='/'>Back</a>");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.configuration.BaeldungException;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.annotation.DeleteRoute;
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.PostRoute;
|
||||||
|
import com.blade.mvc.annotation.PutRoute;
|
||||||
|
import com.blade.mvc.annotation.Route;
|
||||||
|
import com.blade.mvc.http.HttpMethod;
|
||||||
|
import com.blade.mvc.http.Request;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class RouteExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RouteExampleController.class);
|
||||||
|
|
||||||
|
@GetRoute("/route-example")
|
||||||
|
public String get() {
|
||||||
|
return "get.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/route-example")
|
||||||
|
public String post() {
|
||||||
|
return "post.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutRoute("/route-example")
|
||||||
|
public String put() {
|
||||||
|
return "put.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteRoute("/route-example")
|
||||||
|
public String delete() {
|
||||||
|
return "delete.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/another-route-example", method = HttpMethod.GET)
|
||||||
|
public String anotherGet() {
|
||||||
|
return "get.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/allmatch-route-example")
|
||||||
|
public String allmatch() {
|
||||||
|
return "allmatch.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/triggerInternalServerError")
|
||||||
|
public void triggerInternalServerError() {
|
||||||
|
int x = 1 / 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/triggerBaeldungException")
|
||||||
|
public void triggerBaeldungException() throws BaeldungException {
|
||||||
|
throw new BaeldungException("Foobar Exception to threat differently");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/user/foo")
|
||||||
|
public void urlCoveredByNarrowedWebhook(Response response) {
|
||||||
|
response.text("Check out for the WebHook covering '/user/*' in the logs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/load-configuration-in-a-route")
|
||||||
|
public void loadConfigurationInARoute(Response response) {
|
||||||
|
String authors = WebContext.blade()
|
||||||
|
.env("app.authors", "Unknown authors");
|
||||||
|
log.info("[/load-configuration-in-a-route] Loading 'app.authors' from configuration, value: " + authors);
|
||||||
|
response.render("index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/template-output-test")
|
||||||
|
public void templateOutputTest(Request request, Response response) {
|
||||||
|
request.attribute("name", "Blade");
|
||||||
|
response.render("template-output-test.html");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
public class BaeldungException extends RuntimeException {
|
||||||
|
|
||||||
|
public BaeldungException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.handler.DefaultExceptionHandler;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class GlobalExceptionHandler extends DefaultExceptionHandler {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Exception e) {
|
||||||
|
if (e instanceof BaeldungException) {
|
||||||
|
Exception baeldungException = (BaeldungException) e;
|
||||||
|
String msg = baeldungException.getMessage();
|
||||||
|
log.error("[GlobalExceptionHandler] Intercepted an exception to threat with additional logic. Error message: " + msg);
|
||||||
|
WebContext.response()
|
||||||
|
.render("index.html");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
super.handle(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.Blade;
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.loader.BladeLoader;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class LoadConfig implements BladeLoader {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoadConfig.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Blade blade) {
|
||||||
|
String version = WebContext.blade()
|
||||||
|
.env("app.version")
|
||||||
|
.orElse("N/D");
|
||||||
|
String authors = WebContext.blade()
|
||||||
|
.env("app.authors", "Unknown authors");
|
||||||
|
|
||||||
|
log.info("[LoadConfig] loaded 'app.version' (" + version + ") and 'app.authors' (" + authors + ") in a configuration bean");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.task.annotation.Schedule;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class ScheduleExample {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScheduleExample.class);
|
||||||
|
|
||||||
|
@Schedule(name = "baeldungTask", cron = "0 */1 * * * ?")
|
||||||
|
public void runScheduledTask() {
|
||||||
|
log.info("[ScheduleExample] This is a scheduled Task running once per minute.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.blade.sample.interceptors;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.mvc.RouteContext;
|
||||||
|
import com.blade.mvc.hook.WebHook;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class BaeldungHook implements WebHook {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BaeldungHook.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean before(RouteContext ctx) {
|
||||||
|
log.info("[BaeldungHook] called before Route method");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.blade.sample.interceptors;
|
||||||
|
|
||||||
|
import com.blade.mvc.RouteContext;
|
||||||
|
import com.blade.mvc.hook.WebHook;
|
||||||
|
|
||||||
|
public class BaeldungMiddleware implements WebHook {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BaeldungMiddleware.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean before(RouteContext context) {
|
||||||
|
log.info("[BaeldungMiddleware] called before Route method and other WebHooks");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.blade.sample.vo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
@Getter @Setter private String name;
|
||||||
|
@Getter @Setter private String site;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ReflectionToStringBuilder.toString(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
mvc.statics.show-list=true
|
||||||
|
mvc.view.404=my-404.html
|
||||||
|
mvc.view.500=my-500.html
|
||||||
|
app.version=0.0.1
|
||||||
|
app.authors=Andrea Ligios
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 650 B |
|
@ -0,0 +1 @@
|
||||||
|
/* App CSS */
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>File Upload and download test</h1>
|
||||||
|
<form id="uploadForm" enctype="multipart/form-data">
|
||||||
|
<input id="file" type="file" name="file" />
|
||||||
|
<button id="upload" type="button">Upload</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<a href="/">Back</a>
|
||||||
|
<script>
|
||||||
|
var data = new FormData();
|
||||||
|
|
||||||
|
$('#upload').click(function() {
|
||||||
|
$.ajax({
|
||||||
|
url : '/params-file',
|
||||||
|
type : 'POST',
|
||||||
|
cache : false,
|
||||||
|
data : new FormData($('#uploadForm')[0]),
|
||||||
|
processData : false,
|
||||||
|
contentType : false
|
||||||
|
}).done(function(res) {
|
||||||
|
console.log(res);
|
||||||
|
if (res.success) {
|
||||||
|
alert('Ok');
|
||||||
|
} else {
|
||||||
|
alert(res.msg || 'Error');
|
||||||
|
}
|
||||||
|
}).fail(function(res) {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>User POJO post test</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<form id="uploadForm" action="/params/vo" method="post">
|
||||||
|
<span>Person POJO:</span>
|
||||||
|
<input type="text" name="name" placeholder="name"/>
|
||||||
|
<input type="text" name="site" placeholder="site"/>
|
||||||
|
<button id="upload" type="submit">Send user object</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<a href="/">Back</a>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
ALLMATCH called
|
|
@ -0,0 +1 @@
|
||||||
|
DELETE called
|
|
@ -0,0 +1 @@
|
||||||
|
GET called
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Baeldung Blade App • Written by Andrea Ligios</title>
|
||||||
|
<link href="/static/app.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Baeldung Blade App - Showcase</h1>
|
||||||
|
|
||||||
|
<h3>Manual tests</h3>
|
||||||
|
<p>The following are tests which are not covered by integration tests, but that can be run manually in order to check the functionality, either in the browser or in the logs, depending on the case.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="/static/file-upload.html">File Upload</a></li>
|
||||||
|
<li><a href="/static/user-post.html">User POJO Post</a></li>
|
||||||
|
<li><a href="/user/foo">Webhook narrowed to the '/user/*' URL</a></li>
|
||||||
|
<li><a href="/load-configuration-in-a-route">Load Configuration in a Route</a></li>
|
||||||
|
<li><a href="/triggerInternalServerError">Trigger internal server error (and test the custom error 500 page)</a></li>
|
||||||
|
<li><a href="/triggerBaeldungException">Trigger BaeldungException (and test the Global Exception Handler)</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Session value created in App.java</h3>
|
||||||
|
<p>mySessionValue = ${mySessionValue}</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/static/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>404 Not found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Custom Error 404 Page
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>500 Internal Server Error</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1> Custom Error 500 Page </h1>
|
||||||
|
<p> The following error occurred: "<strong>${message}</strong>"</p>
|
||||||
|
<pre> ${stackTrace} </pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
POST called
|
|
@ -0,0 +1 @@
|
||||||
|
PUT called
|
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello, ${name}!</h1>
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AppLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBasicRoute_whenGet_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/basic-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("GET called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBasicRoute_whenPost_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPost("http://localhost:9000/basic-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("POST called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBasicRoute_whenPut_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPut("http://localhost:9000/basic-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("PUT called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBasicRoute_whenDelete_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpDelete("http://localhost:9000/basic-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("DELETE called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AttributesExampleControllerLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRequestAttribute_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/request-attribute-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo(AttributesExampleController.REQUEST_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSessionAttribute_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/session-attribute-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo(AttributesExampleController.SESSION_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHeader_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/header-example");
|
||||||
|
request.addHeader("a-header","foobar");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(httpResponse.getHeaders("a-header")[0].getValue()).isEqualTo("foobar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNoHeader_whenSet_thenRetrieveDefaultValueWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/header-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(httpResponse.getHeaders("a-header")[0].getValue()).isEqualTo(AttributesExampleController.HEADER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ParameterInjectionExampleControllerLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFormParam_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
URIBuilder builder = new URIBuilder("http://localhost:9000/params/form");
|
||||||
|
builder.setParameter("name", "Andrea Ligios");
|
||||||
|
|
||||||
|
final HttpUriRequest request = new HttpGet(builder.build());
|
||||||
|
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("Andrea Ligios");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPathParam_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/params/path/1337");
|
||||||
|
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("1337");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void givenFileParam_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
//
|
||||||
|
// byte[] data = "this is some temp file content".getBytes("UTF-8");
|
||||||
|
// java.nio.file.Path tempFile = Files.createTempFile("baeldung_test_tempfiles", ".tmp");
|
||||||
|
// Files.write(tempFile, data, StandardOpenOption.WRITE);
|
||||||
|
//
|
||||||
|
// //HttpEntity entity = MultipartEntityBuilder.create().addPart("file", new FileBody(tempFile.toFile())).build();
|
||||||
|
// HttpEntity entity = MultipartEntityBuilder.create().addTextBody("field1", "value1")
|
||||||
|
// .addBinaryBody("fileItem", tempFile.toFile(), ContentType.create("application/octet-stream"), "file1.txt").build();
|
||||||
|
//
|
||||||
|
// final HttpPost post = new HttpPost("http://localhost:9000/params-file");
|
||||||
|
// post.setEntity(entity);
|
||||||
|
//
|
||||||
|
// try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create().build().execute(post);) {
|
||||||
|
// assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("file1.txt");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHeader_whenSet_thenRetrieveWithGet() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/params/header");
|
||||||
|
request.addHeader("customheader", "foobar");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("foobar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNoCookie_whenCalled_thenReadDefaultValue() throws Exception {
|
||||||
|
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/params/cookie");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("default value");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class RouteExampleControllerLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRoute_whenGet_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("GET called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRoute_whenPost_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPost("http://localhost:9000/route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("POST called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRoute_whenPut_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPut("http://localhost:9000/route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("PUT called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRoute_whenDelete_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpDelete("http://localhost:9000/route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("DELETE called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAnotherRoute_whenGet_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/another-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("GET called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAllMatchRoute_whenGet_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/allmatch-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("ALLMATCH called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAllMatchRoute_whenPost_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPost("http://localhost:9000/allmatch-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("ALLMATCH called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAllMatchRoute_whenPut_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpPut("http://localhost:9000/allmatch-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("ALLMATCH called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAllMatchRoute_whenDelete_thenCorrectOutput() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpDelete("http://localhost:9000/allmatch-route-example");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("ALLMATCH called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRequestAttribute_whenRenderedWithTemplate_thenCorrectlyEvaluateIt() throws Exception {
|
||||||
|
final HttpUriRequest request = new HttpGet("http://localhost:9000/template-output-test");
|
||||||
|
try (final CloseableHttpResponse httpResponse = HttpClientBuilder.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);) {
|
||||||
|
assertThat(EntityUtils.toString(httpResponse.getEntity())).isEqualTo("<h1>Hello, Blade!</h1>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.java8.lambda.methodreference;
|
||||||
|
|
||||||
|
public class Bicycle {
|
||||||
|
|
||||||
|
private String brand;
|
||||||
|
private Integer frameSize;
|
||||||
|
|
||||||
|
public Bicycle(String brand, Integer frameSize) {
|
||||||
|
this.brand = brand;
|
||||||
|
this.frameSize = frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrand(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getFrameSize() {
|
||||||
|
return frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFrameSize(Integer frameSize) {
|
||||||
|
this.frameSize = frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.java8.lambda.methodreference;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public class BicycleComparator implements Comparator<Bicycle> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Bicycle a, Bicycle b) {
|
||||||
|
return a.getFrameSize()
|
||||||
|
.compareTo(b.getFrameSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.java8.lambda.methodreference;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MethodReferenceExamples {
|
||||||
|
|
||||||
|
private static <T> void doNothingAtAll(Object... o) {
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void referenceToStaticMethod() {
|
||||||
|
List<String> messages = Arrays.asList("Hello", "Baeldung", "readers!");
|
||||||
|
messages.forEach((word) -> {
|
||||||
|
System.out.println(word);
|
||||||
|
});
|
||||||
|
messages.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void referenceToInstanceMethodOfParticularObject() {
|
||||||
|
BicycleComparator bikeFrameSizeComparator = new BicycleComparator();
|
||||||
|
createBicyclesList().stream()
|
||||||
|
.sorted((a, b) -> bikeFrameSizeComparator.compare(a, b));
|
||||||
|
createBicyclesList().stream()
|
||||||
|
.sorted(bikeFrameSizeComparator::compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void referenceToInstanceMethodOfArbitratyObjectOfParticularType() {
|
||||||
|
List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);
|
||||||
|
numbers.stream()
|
||||||
|
.sorted((a, b) -> Integer.compare(a, b));
|
||||||
|
numbers.stream()
|
||||||
|
.sorted(Integer::compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void referenceToConstructor() {
|
||||||
|
BiFunction<String, Integer, Bicycle> bikeCreator = (brand, frameSize) -> new Bicycle(brand, frameSize);
|
||||||
|
BiFunction<String, Integer, Bicycle> bikeCreatorMethodReference = Bicycle::new;
|
||||||
|
List<Bicycle> bikes = new ArrayList<>();
|
||||||
|
bikes.add(bikeCreator.apply("Giant", 50));
|
||||||
|
bikes.add(bikeCreator.apply("Scott", 20));
|
||||||
|
bikes.add(bikeCreatorMethodReference.apply("Trek", 35));
|
||||||
|
bikes.add(bikeCreatorMethodReference.apply("GT", 40));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void limitationsAndAdditionalExamples() {
|
||||||
|
createBicyclesList().forEach(b -> System.out.printf("Bike brand is '%s' and frame size is '%d'%n", b.getBrand(), b.getFrameSize()));
|
||||||
|
createBicyclesList().forEach((o) -> this.doNothingAtAll(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Bicycle> createBicyclesList() {
|
||||||
|
List<Bicycle> bikes = new ArrayList<>();
|
||||||
|
bikes.add(new Bicycle("Giant", 50));
|
||||||
|
bikes.add(new Bicycle("Scott", 20));
|
||||||
|
bikes.add(new Bicycle("Trek", 35));
|
||||||
|
bikes.add(new Bicycle("GT", 40));
|
||||||
|
return bikes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.array.conversions;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class FloatToByteArray {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert float into byte array using Float API floatToIntBits
|
||||||
|
* @param value
|
||||||
|
* @return byte[]
|
||||||
|
*/
|
||||||
|
public static byte[] floatToByteArray(float value) {
|
||||||
|
int intBits = Float.floatToIntBits(value);
|
||||||
|
return new byte[] {(byte) (intBits >> 24), (byte) (intBits >> 16), (byte) (intBits >> 8), (byte) (intBits) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert byte array into float using Float API intBitsToFloat
|
||||||
|
* @param bytes
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static float byteArrayToFloat(byte[] bytes) {
|
||||||
|
int intBits = bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
|
||||||
|
return Float.intBitsToFloat(intBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert float into byte array using ByteBuffer
|
||||||
|
* @param value
|
||||||
|
* @return byte[]
|
||||||
|
*/
|
||||||
|
public static byte[] floatToByteArrayWithByteBuffer(float value) {
|
||||||
|
return ByteBuffer.allocate(4).putFloat(value).array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert byte array into float using ByteBuffer
|
||||||
|
* @param bytes
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static float byteArrayToFloatWithByteBuffer(byte[] bytes) {
|
||||||
|
return ByteBuffer.wrap(bytes).getFloat();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.array.conversions;
|
||||||
|
|
||||||
|
import static com.baeldung.array.conversions.FloatToByteArray.byteArrayToFloat;
|
||||||
|
import static com.baeldung.array.conversions.FloatToByteArray.byteArrayToFloatWithByteBuffer;
|
||||||
|
import static com.baeldung.array.conversions.FloatToByteArray.floatToByteArray;
|
||||||
|
import static com.baeldung.array.conversions.FloatToByteArray.floatToByteArrayWithByteBuffer;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class FloatToByteArrayUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAFloat_thenConvertToByteArray() {
|
||||||
|
assertArrayEquals(new byte[] { 63, -116, -52, -51}, floatToByteArray(1.1f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAByteArray_thenConvertToFloat() {
|
||||||
|
assertEquals(1.1f, byteArrayToFloat(new byte[] { 63, -116, -52, -51}), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAFloat_thenConvertToByteArrayUsingByteBuffer() {
|
||||||
|
assertArrayEquals(new byte[] { 63, -116, -52, -51}, floatToByteArrayWithByteBuffer(1.1f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAByteArray_thenConvertToFloatUsingByteBuffer() {
|
||||||
|
assertEquals(1.1f, byteArrayToFloatWithByteBuffer(new byte[] { 63, -116, -52, -51}), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAFloat_thenConvertToByteArray_thenConvertToFloat() {
|
||||||
|
float floatToConvert = 200.12f;
|
||||||
|
byte[] byteArray = floatToByteArray(floatToConvert);
|
||||||
|
assertEquals(200.12f, byteArrayToFloat(byteArray), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAFloat_thenConvertToByteArrayWithByteBuffer_thenConvertToFloatWithByteBuffer() {
|
||||||
|
float floatToConvert = 30100.42f;
|
||||||
|
byte[] byteArray = floatToByteArrayWithByteBuffer(floatToConvert);
|
||||||
|
assertEquals(30100.42f, byteArrayToFloatWithByteBuffer(byteArray), 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.files;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ListFiles {
|
||||||
|
public static final int DEPTH = 1;
|
||||||
|
|
||||||
|
public Set<String> listFilesUsingJavaIO(String dir) {
|
||||||
|
return Stream.of(new File(dir).listFiles())
|
||||||
|
.filter(file -> !file.isDirectory())
|
||||||
|
.map(File::getName)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> listFilesUsingFileWalk(String dir, int depth) throws IOException {
|
||||||
|
try (Stream<Path> stream = Files.walk(Paths.get(dir), depth)) {
|
||||||
|
return stream.filter(file -> !Files.isDirectory(file))
|
||||||
|
.map(Path::getFileName)
|
||||||
|
.map(Path::toString)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> listFilesUsingFileWalkAndVisitor(String dir) throws IOException {
|
||||||
|
Set<String> fileList = new HashSet<>();
|
||||||
|
Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
if (!Files.isDirectory(file)) {
|
||||||
|
fileList.add(file.getFileName()
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> listFilesUsingDirectoryStream(String dir) throws IOException {
|
||||||
|
Set<String> fileList = new HashSet<>();
|
||||||
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir))) {
|
||||||
|
for (Path path : stream) {
|
||||||
|
if (!Files.isDirectory(path)) {
|
||||||
|
fileList.add(path.getFileName()
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.baeldung.file;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.util.StreamUtils;
|
||||||
|
|
||||||
|
public class FilesClearDataUnitTest {
|
||||||
|
|
||||||
|
public static final String FILE_PATH = "src/test/resources/fileexample.txt";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@After
|
||||||
|
public void setup() throws IOException {
|
||||||
|
PrintWriter writer = new PrintWriter(FILE_PATH);
|
||||||
|
writer.print("This example shows how we can delete the file contents without deleting the file");
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingPrintWritter_thenEmptyFile() throws IOException {
|
||||||
|
PrintWriter writer = new PrintWriter(FILE_PATH);
|
||||||
|
writer.print("");
|
||||||
|
writer.close();
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingPrintWritterWithougObject_thenEmptyFile() throws IOException {
|
||||||
|
new PrintWriter(FILE_PATH).close();
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingFileWriter_thenEmptyFile() throws IOException {
|
||||||
|
new FileWriter(FILE_PATH, false).close();
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingFileOutputStream_thenEmptyFile() throws IOException {
|
||||||
|
new FileOutputStream(FILE_PATH).close();
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingFileUtils_thenEmptyFile() throws IOException {
|
||||||
|
FileUtils.write(new File(FILE_PATH), "", Charset.defaultCharset());
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingNIOFiles_thenEmptyFile() throws IOException {
|
||||||
|
BufferedWriter writer = Files.newBufferedWriter(Paths.get(FILE_PATH));
|
||||||
|
writer.write("");
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingNIOFileChannel_thenEmptyFile() throws IOException {
|
||||||
|
FileChannel.open(Paths.get(FILE_PATH), StandardOpenOption.WRITE).truncate(0).close();
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingFile_whenDeleteContentUsingGuava_thenEmptyFile() throws IOException {
|
||||||
|
File file = new File(FILE_PATH);
|
||||||
|
byte[] empty = new byte[0];
|
||||||
|
com.google.common.io.Files.write(empty, file);
|
||||||
|
|
||||||
|
assertEquals(0, StreamUtils.getStringFromInputStream(new FileInputStream(FILE_PATH)).length());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.file;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.files.ListFiles;
|
||||||
|
|
||||||
|
public class ListFilesUnitTest {
|
||||||
|
|
||||||
|
private ListFiles listFiles = new ListFiles();
|
||||||
|
private String DIRECTORY = "src/test/resources/listFilesUnitTestFolder";
|
||||||
|
private static final int DEPTH = 1;
|
||||||
|
private Set<String> EXPECTED_FILE_LIST = new HashSet<String>() {
|
||||||
|
{
|
||||||
|
add("test.xml");
|
||||||
|
add("employee.json");
|
||||||
|
add("students.json");
|
||||||
|
add("country.txt");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDir_whenUsingJAVAIO_thenListAllFiles() throws IOException {
|
||||||
|
assertEquals(EXPECTED_FILE_LIST, listFiles.listFilesUsingJavaIO(DIRECTORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDir_whenWalkingTree_thenListAllFiles() throws IOException {
|
||||||
|
assertEquals(EXPECTED_FILE_LIST, listFiles.listFilesUsingFileWalk(DIRECTORY,DEPTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDir_whenWalkingTreeWithVisitor_thenListAllFiles() throws IOException {
|
||||||
|
assertEquals(EXPECTED_FILE_LIST, listFiles.listFilesUsingFileWalkAndVisitor(DIRECTORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDir_whenUsingDirectoryStream_thenListAllFiles() throws IOException {
|
||||||
|
assertEquals(EXPECTED_FILE_LIST, listFiles.listFilesUsingDirectoryStream(DIRECTORY));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
This example shows how we can delete the file contents without deleting the file
|
|
@ -0,0 +1 @@
|
||||||
|
This is a sample txt file for unit test ListFilesUnitTest
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -0,0 +1 @@
|
||||||
|
<xml></xml>
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.objects;
|
||||||
|
|
||||||
|
public class Car {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String model;
|
||||||
|
private String color;
|
||||||
|
private int speed;
|
||||||
|
|
||||||
|
public Car(String type, String model, String color) {
|
||||||
|
this.type = type;
|
||||||
|
this.model = model;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(String color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int increaseSpeed(int increment) {
|
||||||
|
if (increment > 0) {
|
||||||
|
this.speed += increment;
|
||||||
|
} else {
|
||||||
|
System.out.println("Increment can't be negative.");
|
||||||
|
}
|
||||||
|
return this.speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int decreaseSpeed(int decrement) {
|
||||||
|
if (decrement > 0 && decrement <= this.speed) {
|
||||||
|
this.speed -= decrement;
|
||||||
|
} else {
|
||||||
|
System.out.println("Decrement can't be negative or greater than current speed.");
|
||||||
|
}
|
||||||
|
return this.speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Car [type=" + type + ", model=" + model + ", color=" + color + ", speed=" + speed + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.objects;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class CarUnitTest {
|
||||||
|
|
||||||
|
private Car car;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
car = new Car("Ford", "Focus", "red");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void when_speedIncreased_then_verifySpeed() {
|
||||||
|
car.increaseSpeed(30);
|
||||||
|
assertEquals(30, car.getSpeed());
|
||||||
|
|
||||||
|
car.increaseSpeed(20);
|
||||||
|
assertEquals(50, car.getSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void when_speedDecreased_then_verifySpeed() {
|
||||||
|
car.increaseSpeed(50);
|
||||||
|
assertEquals(50, car.getSpeed());
|
||||||
|
|
||||||
|
car.decreaseSpeed(30);
|
||||||
|
assertEquals(20, car.getSpeed());
|
||||||
|
|
||||||
|
car.decreaseSpeed(20);
|
||||||
|
assertEquals(0, car.getSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.baeldung.bitwiseoperator.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class BitwiseOperatorUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoIntegers_whenAndOperator_thenNewDecimalNumber() {
|
||||||
|
int value1 = 6;
|
||||||
|
int value2 = 5;
|
||||||
|
int result = value1 & value2;
|
||||||
|
assertEquals(result, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoIntegers_whenOrOperator_thenNewDecimalNumber() {
|
||||||
|
int value1 = 6;
|
||||||
|
int value2 = 5;
|
||||||
|
int result = value1 | value2;
|
||||||
|
assertEquals(result, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoIntegers_whenXorOperator_thenNewDecimalNumber() {
|
||||||
|
int value1 = 6;
|
||||||
|
int value2 = 5;
|
||||||
|
int result = value1 ^ value2;
|
||||||
|
assertEquals(result, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOneInteger_whenNotOperator_thenNewDecimalNumber() {
|
||||||
|
int value1 = 6;
|
||||||
|
int result = ~value1;
|
||||||
|
assertEquals(result, -7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = 12;
|
||||||
|
int rightShift = value >> 2;
|
||||||
|
assertEquals(rightShift, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = -12;
|
||||||
|
int rightShift = value >> 2;
|
||||||
|
assertEquals(rightShift, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = 12;
|
||||||
|
int leftShift = value << 2;
|
||||||
|
assertEquals(leftShift, 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = -12;
|
||||||
|
int leftShift = value << 2;
|
||||||
|
assertEquals(leftShift, -48);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = 12;
|
||||||
|
int unsignedRightShift = value >>> 2;
|
||||||
|
assertEquals(unsignedRightShift, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
|
||||||
|
int value = -12;
|
||||||
|
int unsignedRightShift = value >>> 2;
|
||||||
|
assertEquals(unsignedRightShift, 1073741821);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,19 @@ import kotlin.test.assertTrue
|
||||||
|
|
||||||
class VoidTypesUnitTest {
|
class VoidTypesUnitTest {
|
||||||
|
|
||||||
fun returnTypeAsVoid(): Void? {
|
// Un-commenting below methods will result into compilation error
|
||||||
|
// as the syntax used is incorrect and is used for explanation in tutorial.
|
||||||
|
|
||||||
|
// fun returnTypeAsVoidAttempt1(): Void {
|
||||||
|
// println("Trying with Void as return type")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fun returnTypeAsVoidAttempt2(): Void {
|
||||||
|
// println("Trying with Void as return type")
|
||||||
|
// return null
|
||||||
|
// }
|
||||||
|
|
||||||
|
fun returnTypeAsVoidSuccess(): Void? {
|
||||||
println("Function can have Void as return type")
|
println("Function can have Void as return type")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -36,7 +48,7 @@ class VoidTypesUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun givenVoidReturnType_thenReturnsNullOnly() {
|
fun givenVoidReturnType_thenReturnsNullOnly() {
|
||||||
assertNull(returnTypeAsVoid())
|
assertNull(returnTypeAsVoidSuccess())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
package com.baeldung.java.map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.MultiMapUtils;
|
||||||
|
import org.apache.commons.collections4.MultiValuedMap;
|
||||||
|
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
|
||||||
|
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class MultiValuedMapUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenPuttingMultipleValuesUsingPutMethod_thenReturningAllValues() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
|
||||||
|
map.put("key", "value1");
|
||||||
|
map.put("key", "value2");
|
||||||
|
map.put("key", "value2");
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.get("key")).containsExactly("value1", "value2", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenPuttingMultipleValuesUsingPutAllMethod_thenReturningAllValues() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
|
||||||
|
map.putAll("key", Arrays.asList("value1", "value2", "value2"));
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.get("key")).containsExactly("value1", "value2", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenGettingValueUsingGetMethod_thenReturningValue() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.get("key")).containsExactly("value");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingEntriesMethod_thenReturningMappings() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value1");
|
||||||
|
map.put("key", "value2");
|
||||||
|
|
||||||
|
Collection<Entry<String, String>> entries = (Collection<Entry<String, String>>) map.entries();
|
||||||
|
|
||||||
|
for(Map.Entry<String,String> entry : entries) {
|
||||||
|
assertThat(entry.getKey()).contains("key");
|
||||||
|
assertTrue(entry.getValue().equals("value1") || entry.getValue().equals("value2") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingKeysMethod_thenReturningAllKeys() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertThat(((Collection<String>) map.keys())).contains("key", "key1", "key2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingKeySetMethod_thenReturningAllKeys() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.keySet()).contains("key", "key1", "key2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingValuesMethod_thenReturningAllValues() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value", "value1", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingRemoveMethod_thenReturningUpdatedMap() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value", "value1", "value2");
|
||||||
|
|
||||||
|
map.remove("key");
|
||||||
|
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value1", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingRemoveMappingMethod_thenReturningUpdatedMapAfterMappingRemoved() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value", "value1", "value2");
|
||||||
|
|
||||||
|
map.removeMapping("key", "value");
|
||||||
|
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value1", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingClearMethod_thenReturningEmptyMap() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
assertThat(((Collection<String>) map.values())).contains("value", "value1", "value2");
|
||||||
|
|
||||||
|
map.clear();
|
||||||
|
|
||||||
|
assertTrue(map.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingContainsKeyMethod_thenReturningTrue() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertTrue(map.containsKey("key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingContainsValueMethod_thenReturningTrue() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertTrue(map.containsValue("value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingIsEmptyMethod_thenReturningFalse() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertFalse(map.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiValuesMap_whenUsingSizeMethod_thenReturningElementCount() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key2", "value2");
|
||||||
|
|
||||||
|
assertEquals(3, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayListValuedHashMap_whenPuttingDoubleValues_thenReturningAllValues() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
|
||||||
|
map.put("key", "value1");
|
||||||
|
map.put("key", "value2");
|
||||||
|
map.put("key", "value2");
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.get("key")).containsExactly("value1", "value2", "value2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHashSetValuedHashMap_whenPuttingTwiceTheSame_thenReturningOneValue() {
|
||||||
|
MultiValuedMap<String, String> map = new HashSetValuedHashMap<>();
|
||||||
|
|
||||||
|
map.put("key1", "value1");
|
||||||
|
map.put("key1", "value1");
|
||||||
|
|
||||||
|
assertThat((Collection<String>) map.get("key1")).containsExactly("value1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void givenUnmodifiableMultiValuedMap_whenInserting_thenThrowingException() {
|
||||||
|
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
|
||||||
|
map.put("key", "value1");
|
||||||
|
map.put("key", "value2");
|
||||||
|
MultiValuedMap<String, String> immutableMap = MultiMapUtils.unmodifiableMultiValuedMap(map);
|
||||||
|
|
||||||
|
immutableMap.put("key", "value3");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -71,6 +71,30 @@
|
||||||
<artifactId>tomcat-catalina</artifactId>
|
<artifactId>tomcat-catalina</artifactId>
|
||||||
<version>${tomcat.version}</version>
|
<version>${tomcat.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.igniterealtime.smack</groupId>
|
||||||
|
<artifactId>smack-tcp</artifactId>
|
||||||
|
<version>${smack.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.igniterealtime.smack</groupId>
|
||||||
|
<artifactId>smack-im</artifactId>
|
||||||
|
<version>${smack.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.igniterealtime.smack</groupId>
|
||||||
|
<artifactId>smack-extensions</artifactId>
|
||||||
|
<version>${smack.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.igniterealtime.smack</groupId>
|
||||||
|
<artifactId>smack-java7</artifactId>
|
||||||
|
<version>${smack.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -82,6 +106,7 @@
|
||||||
<commons.collections.version>4.1</commons.collections.version>
|
<commons.collections.version>4.1</commons.collections.version>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<tomcat.version>8.5.24</tomcat.version>
|
<tomcat.version>8.5.24</tomcat.version>
|
||||||
|
<smack.version>4.3.1</smack.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -676,29 +676,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.igniterealtime.smack</groupId>
|
|
||||||
<artifactId>smack-tcp</artifactId>
|
|
||||||
<version>${smack.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.igniterealtime.smack</groupId>
|
|
||||||
<artifactId>smack-im</artifactId>
|
|
||||||
<version>${smack.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.igniterealtime.smack</groupId>
|
|
||||||
<artifactId>smack-extensions</artifactId>
|
|
||||||
<version>${smack.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.igniterealtime.smack</groupId>
|
|
||||||
<artifactId>smack-java7</artifactId>
|
|
||||||
<version>${smack.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -920,7 +897,6 @@
|
||||||
<derive4j.version>1.1.0</derive4j.version>
|
<derive4j.version>1.1.0</derive4j.version>
|
||||||
<mockftpserver.version>2.7.1</mockftpserver.version>
|
<mockftpserver.version>2.7.1</mockftpserver.version>
|
||||||
<commons-net.version>3.6</commons-net.version>
|
<commons-net.version>3.6</commons-net.version>
|
||||||
<smack.version>4.3.1</smack.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -5,3 +5,5 @@
|
||||||
- [Lombok @Builder with Inheritance](https://www.baeldung.com/lombok-builder-inheritance)
|
- [Lombok @Builder with Inheritance](https://www.baeldung.com/lombok-builder-inheritance)
|
||||||
- [Lombok Builder with Default Value](https://www.baeldung.com/lombok-builder-default-value)
|
- [Lombok Builder with Default Value](https://www.baeldung.com/lombok-builder-default-value)
|
||||||
- [Lombok Builder with Custom Setter](https://www.baeldung.com/lombok-builder-custom-setter)
|
- [Lombok Builder with Custom Setter](https://www.baeldung.com/lombok-builder-custom-setter)
|
||||||
|
- [Setting up Lombok with Eclipse and Intellij](https://www.baeldung.com/lombok-ide)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>solid/artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.d;
|
||||||
|
|
||||||
|
public class Keyboard {
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.baeldung.d;
|
||||||
|
|
||||||
|
public class Monitor {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.d;
|
||||||
|
|
||||||
|
public class Windows98Machine {
|
||||||
|
|
||||||
|
private final Keyboard keyboard;
|
||||||
|
private final Monitor monitor;
|
||||||
|
|
||||||
|
public Windows98Machine() {
|
||||||
|
|
||||||
|
monitor = new Monitor();
|
||||||
|
keyboard = new Keyboard();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.d;
|
||||||
|
|
||||||
|
public class Windows98MachineDI {
|
||||||
|
|
||||||
|
private final Keyboard keyboard;
|
||||||
|
private final Monitor monitor;
|
||||||
|
|
||||||
|
public Windows98MachineDI(Keyboard keyboard, Monitor monitor) {
|
||||||
|
this.keyboard = keyboard;
|
||||||
|
this.monitor = monitor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public class BearCarer implements BearCleaner, BearFeeder {
|
||||||
|
|
||||||
|
public void washTheBear() {
|
||||||
|
//I think we missed a spot..
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feedTheBear() {
|
||||||
|
//Tuna tuesdays..
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public interface BearCleaner {
|
||||||
|
void washTheBear();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public interface BearFeeder {
|
||||||
|
void feedTheBear();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public interface BearKeeper {
|
||||||
|
|
||||||
|
void washTheBear();
|
||||||
|
void feedTheBear();
|
||||||
|
void petTheBear();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public interface BearPetter {
|
||||||
|
void petTheBear();
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.i;
|
||||||
|
|
||||||
|
public class CrazyPerson implements BearPetter {
|
||||||
|
|
||||||
|
public void petTheBear() {
|
||||||
|
//Good luck with that!
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.l;
|
||||||
|
|
||||||
|
public interface Car {
|
||||||
|
|
||||||
|
void turnOnEngine();
|
||||||
|
void accelerate();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.l;
|
||||||
|
|
||||||
|
public class ElectricCar implements Car {
|
||||||
|
|
||||||
|
public void turnOnEngine() {
|
||||||
|
throw new AssertionError("I don't have an engine!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void accelerate() {
|
||||||
|
//this acceleration is crazy!
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.l;
|
||||||
|
|
||||||
|
public class Engine {
|
||||||
|
|
||||||
|
public void on(){
|
||||||
|
//vroom.
|
||||||
|
}
|
||||||
|
|
||||||
|
public void powerOn(int amount){
|
||||||
|
//do something
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.l;
|
||||||
|
|
||||||
|
public class MotorCar implements Car {
|
||||||
|
|
||||||
|
private Engine engine;
|
||||||
|
|
||||||
|
//Constructors, getters + setters
|
||||||
|
|
||||||
|
public void turnOnEngine() {
|
||||||
|
//turn on the engine!
|
||||||
|
engine.on();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void accelerate() {
|
||||||
|
//move forward!
|
||||||
|
engine.powerOn(1000);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.baeldung.o;
|
||||||
|
|
||||||
|
public class Guitar {
|
||||||
|
|
||||||
|
private String make;
|
||||||
|
private String model;
|
||||||
|
private int volume;
|
||||||
|
|
||||||
|
//Constructors, getters & setters
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.o;
|
||||||
|
|
||||||
|
public class SuperCoolGuitarWithFlames extends Guitar {
|
||||||
|
|
||||||
|
private String flameColour;
|
||||||
|
|
||||||
|
//constructor, getters + setters
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.s;
|
||||||
|
|
||||||
|
public class BadBook {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String author;
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
//constructor, getters and setters
|
||||||
|
|
||||||
|
|
||||||
|
//methods that directly relate to the book properties
|
||||||
|
public String replaceWordInText(String word){
|
||||||
|
return text.replaceAll(word, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWordInText(String word){
|
||||||
|
return text.contains(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
//methods for outputting text to console - should this really be here?
|
||||||
|
void printTextToConsole(){
|
||||||
|
//our code for formatting and printing the text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.s;
|
||||||
|
|
||||||
|
public class BookPrinter {
|
||||||
|
|
||||||
|
//methods for outputting text
|
||||||
|
void printTextToConsole(String text){
|
||||||
|
//our code for formatting and printing the text
|
||||||
|
}
|
||||||
|
|
||||||
|
void printTextToAnotherMedium(String text){
|
||||||
|
//code for writing to any other location..
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.s;
|
||||||
|
|
||||||
|
public class GoodBook {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String author;
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
//constructor, getters and setters
|
||||||
|
|
||||||
|
//methods that directly relate to the book properties
|
||||||
|
public String replaceWordInText(String word){
|
||||||
|
return text.replaceAll(word, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWordInText(String word){
|
||||||
|
return text.contains(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,15 +25,15 @@ class Passenger {
|
||||||
|
|
||||||
@Basic(optional = false)
|
@Basic(optional = false)
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private int seatNumber;
|
private Integer seatNumber;
|
||||||
|
|
||||||
private Passenger(String firstName, String lastName, int seatNumber) {
|
private Passenger(String firstName, String lastName, Integer seatNumber) {
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
this.seatNumber = seatNumber;
|
this.seatNumber = seatNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Passenger from(String firstName, String lastName, int seatNumber) {
|
static Passenger from(String firstName, String lastName, Integer seatNumber) {
|
||||||
return new Passenger(firstName, lastName, seatNumber);
|
return new Passenger(firstName, lastName, seatNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ class Passenger {
|
||||||
return lastName;
|
return lastName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getSeatNumber() {
|
Integer getSeatNumber() {
|
||||||
return seatNumber;
|
return seatNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,29 @@
|
||||||
package com.baeldung.passenger;
|
package com.baeldung.passenger;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.ExampleMatcher;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
public class PassengerRepositoryIntegrationTest {
|
public class PassengerRepositoryIntegrationTest {
|
||||||
|
@ -45,7 +51,7 @@ public class PassengerRepositoryIntegrationTest {
|
||||||
assertEquals(1, passengers.size());
|
assertEquals(1, passengers.size());
|
||||||
|
|
||||||
Passenger actual = passengers.get(0);
|
Passenger actual = passengers.get(0);
|
||||||
assertEquals(actual, expected);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -54,16 +60,17 @@ public class PassengerRepositoryIntegrationTest {
|
||||||
|
|
||||||
Passenger actual = repository.findFirstByOrderBySeatNumberAsc();
|
Passenger actual = repository.findFirstByOrderBySeatNumberAsc();
|
||||||
|
|
||||||
assertEquals(actual, expected);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenSeveralPassengersWhenFindPageSortedByThenThePassengerInTheFirstFilledSeatIsReturned() {
|
public void givenSeveralPassengersWhenFindPageSortedByThenThePassengerInTheFirstFilledSeatIsReturned() {
|
||||||
Passenger expected = Passenger.from("Fred", "Bloggs", 22);
|
Passenger expected = Passenger.from("Fred", "Bloggs", 22);
|
||||||
|
|
||||||
Page<Passenger> page = repository.findAll(PageRequest.of(0, 1, Sort.by(Sort.Direction.ASC, "seatNumber")));
|
Page<Passenger> page = repository.findAll(PageRequest.of(0, 1,
|
||||||
|
Sort.by(Sort.Direction.ASC, "seatNumber")));
|
||||||
|
|
||||||
assertEquals(page.getContent().size(), 1);
|
assertEquals(1, page.getContent().size());
|
||||||
|
|
||||||
Passenger actual = page.getContent().get(0);
|
Passenger actual = page.getContent().get(0);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
|
@ -95,4 +102,68 @@ public class PassengerRepositoryIntegrationTest {
|
||||||
assertThat(passengers, contains(fred, ricki, jill, siya, eve));
|
assertThat(passengers, contains(fred, ricki, jill, siya, eve));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPassengers_whenFindByExampleDefaultMatcher_thenExpectedReturned() {
|
||||||
|
Example<Passenger> example = Example.of(Passenger.from("Fred", "Bloggs", null));
|
||||||
|
|
||||||
|
Optional<Passenger> actual = repository.findOne(example);
|
||||||
|
|
||||||
|
assertTrue(actual.isPresent());
|
||||||
|
assertEquals(Passenger.from("Fred", "Bloggs", 22), actual.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPassengers_whenFindByExampleCaseInsensitiveMatcher_thenExpectedReturned() {
|
||||||
|
ExampleMatcher caseInsensitiveExampleMatcher = ExampleMatcher.matchingAll().withIgnoreCase();
|
||||||
|
Example<Passenger> example = Example.of(Passenger.from("fred", "bloggs", null),
|
||||||
|
caseInsensitiveExampleMatcher);
|
||||||
|
|
||||||
|
Optional<Passenger> actual = repository.findOne(example);
|
||||||
|
|
||||||
|
assertTrue(actual.isPresent());
|
||||||
|
assertEquals(Passenger.from("Fred", "Bloggs", 22), actual.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPassengers_whenFindByExampleCustomMatcher_thenExpectedReturned() {
|
||||||
|
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||||
|
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||||
|
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||||
|
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||||
|
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||||
|
|
||||||
|
ExampleMatcher customExampleMatcher = ExampleMatcher.matchingAny().withMatcher("firstName",
|
||||||
|
ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase()).withMatcher("lastName",
|
||||||
|
ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase());
|
||||||
|
|
||||||
|
Example<Passenger> example = Example.of(Passenger.from("e", "s", null),
|
||||||
|
customExampleMatcher);
|
||||||
|
|
||||||
|
List<Passenger> passengers = repository.findAll(example);
|
||||||
|
|
||||||
|
assertThat(passengers, contains(jill, eve, fred, siya));
|
||||||
|
assertThat(passengers, not(contains(ricki)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPassengers_whenFindByIgnoringMatcher_thenExpectedReturned() {
|
||||||
|
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||||
|
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||||
|
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||||
|
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||||
|
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||||
|
|
||||||
|
ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAny().withMatcher("lastName",
|
||||||
|
ExampleMatcher.GenericPropertyMatchers.startsWith().ignoreCase()).withIgnorePaths("firstName", "seatNumber");
|
||||||
|
|
||||||
|
Example<Passenger> example = Example.of(Passenger.from(null, "b", null),
|
||||||
|
ignoringExampleMatcher);
|
||||||
|
|
||||||
|
List<Passenger> passengers = repository.findAll(example);
|
||||||
|
|
||||||
|
assertThat(passengers, contains(fred, ricki));
|
||||||
|
assertThat(passengers, not(contains(jill)));
|
||||||
|
assertThat(passengers, not(contains(eve)));
|
||||||
|
assertThat(passengers, not(contains(siya)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
3
pom.xml
3
pom.xml
|
@ -367,6 +367,8 @@
|
||||||
<module>axon</module>
|
<module>axon</module>
|
||||||
<module>azure</module>
|
<module>azure</module>
|
||||||
|
|
||||||
|
<module>blade</module>
|
||||||
|
|
||||||
<module>bootique</module>
|
<module>bootique</module>
|
||||||
|
|
||||||
<module>cas/cas-secured-app</module>
|
<module>cas/cas-secured-app</module>
|
||||||
|
@ -714,7 +716,6 @@
|
||||||
<module>spring-rest-simple</module>
|
<module>spring-rest-simple</module>
|
||||||
<module>spring-resttemplate</module>
|
<module>spring-resttemplate</module>
|
||||||
<module>spring-roo</module>
|
<module>spring-roo</module>
|
||||||
|
|
||||||
<module>spring-security-acl</module>
|
<module>spring-security-acl</module>
|
||||||
<module>spring-security-angular/server</module>
|
<module>spring-security-angular/server</module>
|
||||||
<module>spring-security-cache-control</module>
|
<module>spring-security-cache-control</module>
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
@ -29,6 +33,13 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Problem Spring Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.zalando</groupId>
|
||||||
|
<artifactId>problem-spring-web</artifactId>
|
||||||
|
<version>${problem-spring-web.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- ShedLock -->
|
<!-- ShedLock -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.javacrumbs.shedlock</groupId>
|
<groupId>net.javacrumbs.shedlock</groupId>
|
||||||
|
@ -139,6 +150,7 @@
|
||||||
<guava.version>18.0</guava.version>
|
<guava.version>18.0</guava.version>
|
||||||
<git-commit-id-plugin.version>2.2.4</git-commit-id-plugin.version>
|
<git-commit-id-plugin.version>2.2.4</git-commit-id-plugin.version>
|
||||||
<modelmapper.version>2.3.2</modelmapper.version>
|
<modelmapper.version>2.3.2</modelmapper.version>
|
||||||
|
<problem-spring-web.version>0.23.0</problem-spring-web.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.baeldung.boot;
|
package com.baeldung.boot;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.boot.problem;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
|
||||||
|
@ComponentScan("com.baeldung.boot.problem")
|
||||||
|
public class SpringProblemApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.setProperty("spring.profiles.active", "problem");
|
||||||
|
SpringApplication.run(SpringProblemApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.boot.problem.advice;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.zalando.problem.spring.web.advice.ProblemHandling;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class ExceptionHandler implements ProblemHandling {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.boot.problem.advice;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class SecurityExceptionHandler implements SecurityAdviceTrait {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.boot.problem.configuration;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.zalando.problem.ProblemModule;
|
||||||
|
import org.zalando.problem.validation.ConstraintViolationProblemModule;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ProblemDemoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObjectMapper objectMapper() {
|
||||||
|
return new ObjectMapper().registerModules(new ProblemModule(), new ConstraintViolationProblemModule());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.boot.problem.configuration;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@Import(SecurityProblemSupport.class)
|
||||||
|
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SecurityProblemSupport problemSupport;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.csrf().disable();
|
||||||
|
|
||||||
|
http.authorizeRequests()
|
||||||
|
.antMatchers("/")
|
||||||
|
.permitAll();
|
||||||
|
|
||||||
|
http.exceptionHandling()
|
||||||
|
.authenticationEntryPoint(problemSupport)
|
||||||
|
.accessDeniedHandler(problemSupport);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.boot.problem.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.baeldung.boot.problem.dto.Task;
|
||||||
|
import com.baeldung.boot.problem.problems.TaskNotFoundProblem;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/tasks")
|
||||||
|
public class ProblemDemoController {
|
||||||
|
|
||||||
|
private static final Map<Long, Task> MY_TASKS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
MY_TASKS = new HashMap<>();
|
||||||
|
MY_TASKS.put(1L, new Task(1L, "My first task"));
|
||||||
|
MY_TASKS.put(2L, new Task(2L, "My second task"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public List<Task> getTasks() {
|
||||||
|
return new ArrayList<>(MY_TASKS.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public Task getTasks(@PathVariable("id") Long taskId) {
|
||||||
|
if (MY_TASKS.containsKey(taskId)) {
|
||||||
|
return MY_TASKS.get(taskId);
|
||||||
|
} else {
|
||||||
|
throw new TaskNotFoundProblem(taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public void updateTask(@PathVariable("id") Long id) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public void deleteTask(@PathVariable("id") Long id) {
|
||||||
|
throw new AccessDeniedException("You can't delete this task");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.boot.problem.dto;
|
||||||
|
|
||||||
|
public class Task {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public Task() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task(Long id, String description) {
|
||||||
|
this.id = id;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.boot.problem.problems;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.zalando.problem.AbstractThrowableProblem;
|
||||||
|
import org.zalando.problem.Status;
|
||||||
|
|
||||||
|
public class TaskNotFoundProblem extends AbstractThrowableProblem {
|
||||||
|
|
||||||
|
private static final URI TYPE = URI.create("https://example.org/not-found");
|
||||||
|
|
||||||
|
public TaskNotFoundProblem(Long taskId) {
|
||||||
|
super(TYPE, "Not found", Status.NOT_FOUND, String.format("Task '%s' not found", taskId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import org.springframework.stereotype.Component;
|
||||||
@Component
|
@Component
|
||||||
class TaskScheduler {
|
class TaskScheduler {
|
||||||
|
|
||||||
@Scheduled(cron = "*/15 * * * * *")
|
@Scheduled(cron = "*/15 * * * *")
|
||||||
@SchedulerLock(name = "TaskScheduler_scheduledTask", lockAtLeastForString = "PT5M", lockAtMostForString = "PT14M")
|
@SchedulerLock(name = "TaskScheduler_scheduledTask", lockAtLeastForString = "PT5M", lockAtMostForString = "PT14M")
|
||||||
public void scheduledTask() {
|
public void scheduledTask() {
|
||||||
System.out.println("Running ShedLock task");
|
System.out.println("Running ShedLock task");
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
spring.resources.add-mappings=false
|
||||||
|
spring.mvc.throw-exception-if-no-handler-found=true
|
||||||
|
spring.http.encoding.force=true
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.baeldung.boot.problem.controller;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
import com.baeldung.boot.problem.SpringProblemApplication;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = SpringProblemApplication.class)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
public class ProblemDemoControllerIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRequestingAllTasks_thenReturnSuccessfulResponseWithArrayWithTwoTasks() throws Exception {
|
||||||
|
mockMvc.perform(get("/tasks").contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(jsonPath("$.length()", equalTo(2)))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRequestingExistingTask_thenReturnSuccessfulResponse() throws Exception {
|
||||||
|
mockMvc.perform(get("/tasks/1").contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(jsonPath("$.id", equalTo(1)))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRequestingMissingTask_thenReturnNotFoundProblemResponse() throws Exception {
|
||||||
|
mockMvc.perform(get("/tasks/5").contentType(MediaType.APPLICATION_PROBLEM_JSON_VALUE))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(jsonPath("$.title", equalTo("Not found")))
|
||||||
|
.andExpect(jsonPath("$.status", equalTo(404)))
|
||||||
|
.andExpect(jsonPath("$.detail", equalTo("Task '5' not found")))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMakePutCall_thenReturnNotImplementedProblemResponse() throws Exception {
|
||||||
|
mockMvc.perform(put("/tasks/1").contentType(MediaType.APPLICATION_PROBLEM_JSON_VALUE))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(jsonPath("$.title", equalTo("Not Implemented")))
|
||||||
|
.andExpect(jsonPath("$.status", equalTo(501)))
|
||||||
|
.andExpect(status().isNotImplemented());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMakeDeleteCall_thenReturnForbiddenProblemResponse() throws Exception {
|
||||||
|
mockMvc.perform(delete("/tasks/2").contentType(MediaType.APPLICATION_PROBLEM_JSON_VALUE))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(jsonPath("$.title", equalTo("Forbidden")))
|
||||||
|
.andExpect(jsonPath("$.status", equalTo(403)))
|
||||||
|
.andExpect(jsonPath("$.detail", equalTo("You can't delete this task")))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ScheduleJobsByProfile {
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ScheduleJobsByProfile.class);
|
||||||
|
|
||||||
|
@Profile("prod")
|
||||||
|
@Bean
|
||||||
|
public ScheduledJob scheduledJob()
|
||||||
|
{
|
||||||
|
return new ScheduledJob("@Profile");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
public class ScheduledJob {
|
||||||
|
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
public ScheduledJob(String source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ScheduledJob.class);
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = 60000)
|
||||||
|
public void cleanTempDir() {
|
||||||
|
LOG.info("Cleaning temp directory via {}", source);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ScheduledJobsWithBoolean {
|
||||||
|
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(ScheduledJobsWithBoolean.class);
|
||||||
|
|
||||||
|
@Value("${jobs.enabled:true}")
|
||||||
|
private boolean isEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A scheduled job controlled via application property. The job always
|
||||||
|
* executes, but the logic inside is protected by a configurable boolean
|
||||||
|
* flag.
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedDelay = 60000)
|
||||||
|
public void cleanTempDirectory() {
|
||||||
|
if(isEnabled) {
|
||||||
|
LOG.info("Cleaning temp directory via boolean flag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ScheduledJobsWithConditional
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This uses @ConditionalOnProperty to conditionally create a bean, which itself
|
||||||
|
* is a scheduled job.
|
||||||
|
* @return ScheduledJob
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(value = "jobs.enabled", matchIfMissing = true, havingValue = "true")
|
||||||
|
public ScheduledJob runMyCronTask() {
|
||||||
|
return new ScheduledJob("@ConditionalOnProperty");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ScheduledJobsWithExpression
|
||||||
|
{
|
||||||
|
private final static Logger LOG =
|
||||||
|
LoggerFactory.getLogger(ScheduledJobsWithExpression.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A scheduled job controlled via application property. The job always
|
||||||
|
* executes, but the logic inside is protected by a configurable boolean
|
||||||
|
* flag.
|
||||||
|
*/
|
||||||
|
@Scheduled(cron = "${jobs.cronSchedule:-}")
|
||||||
|
public void cleanTempDirectory() {
|
||||||
|
LOG.info("Cleaning temp directory via placeholder");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.scheduling;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableScheduling
|
||||||
|
public class SchedulingApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SchedulingApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@ Module for the articles that are part of the Spring REST E-book:
|
||||||
|
|
||||||
1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
||||||
2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring)
|
2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring)
|
||||||
|
3. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue