Merge branch 'master' into BAEL-20863-move-spring-boot-ctx-fluent
This commit is contained in:
@@ -15,15 +15,18 @@
|
||||
|
||||
<modules>
|
||||
<module>spring-boot-admin</module>
|
||||
<module>spring-boot-custom-starter</module>
|
||||
<module>spring-boot-artifacts</module>
|
||||
<module>spring-boot-ctx-fluent</module>
|
||||
<module>spring-boot-autoconfiguration</module>
|
||||
<module>spring-boot-camel</module>
|
||||
<module>spring-boot-custom-starter</module>
|
||||
<module>spring-boot-crud</module>
|
||||
<module>spring-boot-data</module>
|
||||
<!-- <module>spring-boot-gradle</module> --> <!-- Not a maven project -->
|
||||
<module>spring-boot-keycloak</module>
|
||||
<module>spring-boot-logging-log4j2</module>
|
||||
<module>spring-boot-mvc-birt</module>
|
||||
<module>spring-boot-performance</module>
|
||||
<module>spring-boot-nashorn</module>
|
||||
<module>spring-boot-properties</module>
|
||||
<module>spring-boot-springdoc</module>
|
||||
<module>spring-boot-testing</module>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
## Spring Boot Camel
|
||||
|
||||
This module contains articles about Spring Boot with Apache Camel
|
||||
|
||||
### Example for the Article on Camel API with SpringBoot
|
||||
|
||||
To start, run:
|
||||
|
||||
`mvn spring-boot:run`
|
||||
|
||||
Then, make a POST http request to:
|
||||
|
||||
`http://localhost:8080/camel/api/bean`
|
||||
|
||||
Include the HEADER: Content-Type: application/json,
|
||||
|
||||
and a BODY Payload like:
|
||||
|
||||
`{"id": 1,"name": "World"}`
|
||||
|
||||
We will get a return code of 201 and the response: `Hello, World` - if the transform() method from Application class is uncommented and the process() method is commented
|
||||
|
||||
or return code of 201 and the response: `{"id": 10,"name": "Hello, World"}` - if the transform() method from Application class is commented and the process() method is uncommented
|
||||
|
||||
## Relevant articles:
|
||||
|
||||
- [Apache Camel with Spring Boot](https://www.baeldung.com/apache-camel-spring-boot)
|
||||
@@ -0,0 +1,74 @@
|
||||
<?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.example</groupId>
|
||||
<artifactId>spring-boot-camel</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-camel</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||
<artifactId>spring-boot-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-servlet-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-jackson-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-swagger-java-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-spring-boot-starter</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>spring-boot:run</defaultGoal>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<camel.version>2.19.1</camel.version>
|
||||
<spring-boot-starter.version>1.5.4.RELEASE</spring-boot-starter.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.camel.CamelContext;
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
import org.apache.camel.component.servlet.CamelHttpTransportServlet;
|
||||
import org.apache.camel.impl.DefaultCamelContext;
|
||||
import org.apache.camel.model.rest.RestBindingMode;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages="com.baeldung.camel")
|
||||
public class Application{
|
||||
|
||||
@Value("${server.port}")
|
||||
String serverPort;
|
||||
|
||||
@Value("${baeldung.api.path}")
|
||||
String contextPath;
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean servletRegistrationBean() {
|
||||
ServletRegistrationBean servlet = new ServletRegistrationBean(new CamelHttpTransportServlet(), contextPath+"/*");
|
||||
servlet.setName("CamelServlet");
|
||||
return servlet;
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
class RestApi extends RouteBuilder {
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
|
||||
CamelContext context = new DefaultCamelContext();
|
||||
|
||||
|
||||
// http://localhost:8080/camel/api-doc
|
||||
restConfiguration().contextPath(contextPath) //
|
||||
.port(serverPort)
|
||||
.enableCORS(true)
|
||||
.apiContextPath("/api-doc")
|
||||
.apiProperty("api.title", "Test REST API")
|
||||
.apiProperty("api.version", "v1")
|
||||
.apiProperty("cors", "true") // cross-site
|
||||
.apiContextRouteId("doc-api")
|
||||
.component("servlet")
|
||||
.bindingMode(RestBindingMode.json)
|
||||
.dataFormatProperty("prettyPrint", "true");
|
||||
/**
|
||||
The Rest DSL supports automatic binding json/xml contents to/from
|
||||
POJOs using Camels Data Format.
|
||||
By default the binding mode is off, meaning there is no automatic
|
||||
binding happening for incoming and outgoing messages.
|
||||
You may want to use binding if you develop POJOs that maps to
|
||||
your REST services request and response types.
|
||||
*/
|
||||
|
||||
rest("/api/").description("Teste REST Service")
|
||||
.id("api-route")
|
||||
.post("/bean")
|
||||
.produces(MediaType.APPLICATION_JSON)
|
||||
.consumes(MediaType.APPLICATION_JSON)
|
||||
// .get("/hello/{place}")
|
||||
.bindingMode(RestBindingMode.auto)
|
||||
.type(MyBean.class)
|
||||
.enableCORS(true)
|
||||
// .outType(OutBean.class)
|
||||
|
||||
.to("direct:remoteService");
|
||||
|
||||
|
||||
from("direct:remoteService")
|
||||
.routeId("direct-route")
|
||||
.tracing()
|
||||
.log(">>> ${body.id}")
|
||||
.log(">>> ${body.name}")
|
||||
// .transform().simple("blue ${in.body.name}")
|
||||
.process(new Processor() {
|
||||
@Override
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
MyBean bodyIn = (MyBean) exchange.getIn().getBody();
|
||||
|
||||
ExampleServices.example(bodyIn);
|
||||
|
||||
exchange.getIn().setBody(bodyIn);
|
||||
}
|
||||
})
|
||||
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201));
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
/**
|
||||
* a Mock class to show how some other layer
|
||||
* (a persistence layer, for instance)
|
||||
* could be used insida a Camel
|
||||
*
|
||||
*/
|
||||
public class ExampleServices {
|
||||
|
||||
public static void example(MyBean bodyIn) {
|
||||
bodyIn.setName( "Hello, " + bodyIn.getName() );
|
||||
bodyIn.setId(bodyIn.getId()*10);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.camel;
|
||||
|
||||
public class MyBean {
|
||||
private Integer id;
|
||||
private String name;
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
logging.config=classpath:logback.xml
|
||||
|
||||
# the options from org.apache.camel.spring.boot.CamelConfigurationProperties can be configured here
|
||||
camel.springboot.name=MyCamel
|
||||
|
||||
# lets listen on all ports to ensure we can be invoked from the pod IP
|
||||
server.address=0.0.0.0
|
||||
management.address=0.0.0.0
|
||||
|
||||
# lets use a different management port in case you need to listen to HTTP requests on 8080
|
||||
management.port=8081
|
||||
|
||||
# disable all management enpoints except health
|
||||
endpoints.enabled = true
|
||||
endpoints.health.enabled = true
|
||||
@@ -0,0 +1,27 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
# for example purposes of Camel version 2.18 and below
|
||||
baeldung:
|
||||
api:
|
||||
path: '/camel'
|
||||
|
||||
camel:
|
||||
springboot:
|
||||
# The Camel context name
|
||||
name: ServicesRest
|
||||
|
||||
# Binding health checks to a different port
|
||||
management:
|
||||
port: 8081
|
||||
|
||||
# disable all management enpoints except health
|
||||
endpoints:
|
||||
enabled: false
|
||||
health:
|
||||
enabled: true
|
||||
|
||||
# The application configuration properties
|
||||
quickstart:
|
||||
generateOrderPeriod: 10s
|
||||
processOrderPeriod: 30s
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoders are assigned the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.camel.Application;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
## Spring boot CRUD
|
||||
|
||||
This module contains articles about Spring Boot CRUD Operations
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring Boot CRUD Application with Thymeleaf](https://www.baeldung.com/spring-boot-crud-thymeleaf)
|
||||
- [Using a Spring Boot Application as a Dependency](https://www.baeldung.com/spring-boot-dependency)
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-boot-crud</artifactId>
|
||||
<name>spring-boot-crud</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-boot-crud</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<classifier>exec</classifier>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<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>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.crud;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan(basePackages={"com.baeldung.crud"})
|
||||
@EnableJpaRepositories(basePackages="com.baeldung.crud.repositories")
|
||||
@EnableTransactionManagement
|
||||
@EntityScan(basePackages="com.baeldung.crud.entities")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.baeldung.crud.controllers;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import com.baeldung.crud.entities.User;
|
||||
import com.baeldung.crud.repositories.UserRepository;
|
||||
|
||||
@Controller
|
||||
public class UserController {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
public UserController(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/signup")
|
||||
public String showSignUpForm(User user) {
|
||||
return "add-user";
|
||||
}
|
||||
|
||||
@PostMapping("/adduser")
|
||||
public String addUser(@Valid User user, BindingResult result, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
return "add-user";
|
||||
}
|
||||
|
||||
userRepository.save(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
public String showUpdateForm(@PathVariable("id") long id, Model model) {
|
||||
User user = userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
|
||||
model.addAttribute("user", user);
|
||||
return "update-user";
|
||||
}
|
||||
|
||||
@PostMapping("/update/{id}")
|
||||
public String updateUser(@PathVariable("id") long id, @Valid User user, BindingResult result, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
user.setId(id);
|
||||
return "update-user";
|
||||
}
|
||||
|
||||
userRepository.save(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
public String deleteUser(@PathVariable("id") long id, Model model) {
|
||||
User user = userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
|
||||
userRepository.delete(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.crud.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
@NotBlank(message = "Name is mandatory")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "Email is mandatory")
|
||||
private String email;
|
||||
|
||||
public User() {}
|
||||
|
||||
public User(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" + "id=" + id + ", name=" + name + ", email=" + email + '}';
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.crud.repositories;
|
||||
|
||||
import com.baeldung.crud.entities.User;
|
||||
import java.util.List;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends CrudRepository<User, Long> {
|
||||
|
||||
List<User> findByName(String name);
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Add User</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container my-5">
|
||||
<h2 class="mb-5">New User</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form action="#" th:action="@{/adduser}" th:object="${user}" method="post">
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="name" class="col-form-label">Name</label>
|
||||
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name">
|
||||
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="email" class="col-form-label">Email</label>
|
||||
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email">
|
||||
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mt-5">
|
||||
<input type="submit" class="btn btn-primary" value="Add User">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Users</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div th:switch="${users}" class="container my-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h2 th:case="null">No users yet!</h2>
|
||||
<div th:case="*">
|
||||
<h2 class="my-5">Users</h2>
|
||||
<table class="table table-striped table-responsive-md">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Edit</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user : ${users}">
|
||||
<td th:text="${user.name}"></td>
|
||||
<td th:text="${user.email}"></td>
|
||||
<td><a th:href="@{/edit/{id}(id=${user.id})}" class="btn btn-primary"><i class="fas fa-user-edit ml-2"></i></a></td>
|
||||
<td><a th:href="@{/delete/{id}(id=${user.id})}" class="btn btn-primary"><i class="fas fa-user-times ml-2"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="my-5"><a href="/signup" class="btn btn-primary"><i class="fas fa-user-plus ml-2"></i></a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Update User</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container my-5">
|
||||
<h2 class="mb-5">Update User</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form action="#" th:action="@{/update/{id}(id=${user.id})}" th:object="${user}" method="post">
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="name" class="col-form-label">Name</label>
|
||||
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name">
|
||||
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="email" class="col-form-label">Email</label>
|
||||
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email">
|
||||
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mt-5">
|
||||
<input type="submit" class="btn btn-primary" value="Update User">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.baeldung.crud;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
||||
import com.baeldung.crud.controllers.UserController;
|
||||
import com.baeldung.crud.entities.User;
|
||||
import com.baeldung.crud.repositories.UserRepository;
|
||||
|
||||
public class UserControllerUnitTest {
|
||||
|
||||
private static UserController userController;
|
||||
private static UserRepository mockedUserRepository;
|
||||
private static BindingResult mockedBindingResult;
|
||||
private static Model mockedModel;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpUserControllerInstance() {
|
||||
mockedUserRepository = mock(UserRepository.class);
|
||||
mockedBindingResult = mock(BindingResult.class);
|
||||
mockedModel = mock(Model.class);
|
||||
userController = new UserController(mockedUserRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledshowSignUpForm_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
assertThat(userController.showSignUpForm(user)).isEqualTo("add-user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledaddUserAndValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(false);
|
||||
|
||||
assertThat(userController.addUser(user, mockedBindingResult, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledaddUserAndInValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(true);
|
||||
|
||||
assertThat(userController.addUser(user, mockedBindingResult, mockedModel)).isEqualTo("add-user");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenCalledshowUpdateForm_thenIllegalArgumentException() {
|
||||
assertThat(userController.showUpdateForm(0, mockedModel)).isEqualTo("update-user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledupdateUserAndValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(false);
|
||||
|
||||
assertThat(userController.updateUser(1l, user, mockedBindingResult, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledupdateUserAndInValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(true);
|
||||
|
||||
assertThat(userController.updateUser(1l, user, mockedBindingResult, mockedModel)).isEqualTo("update-user");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenCalleddeleteUser_thenIllegalArgumentException() {
|
||||
assertThat(userController.deleteUser(1l, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.crud;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.crud.entities.User;
|
||||
|
||||
public class UserUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenCalledGetName_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
assertThat(user.getName()).isEqualTo("Julie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledGetEmail_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
assertThat(user.getEmail()).isEqualTo("julie@domain.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledSetName_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
user.setName("John");
|
||||
|
||||
assertThat(user.getName()).isEqualTo("John");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledSetEmail_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
user.setEmail("john@domain.com");
|
||||
|
||||
assertThat(user.getEmail()).isEqualTo("john@domain.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledtoString_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
assertThat(user.toString()).isEqualTo("User{id=0, name=Julie, email=julie@domain.com}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/logs/
|
||||
/bin/
|
||||
/mvnw
|
||||
/mvnw.cmd
|
||||
@@ -0,0 +1,8 @@
|
||||
## Spring Boot Logging with Log4j 2
|
||||
|
||||
This module contains articles about logging in Spring Boot projects with Log4j 2.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Logging in Spring Boot](https://www.baeldung.com/spring-boot-logging)
|
||||
- [Logging to Graylog with Spring Boot](https://www.baeldung.com/graylog-with-spring-boot)
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?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>
|
||||
<artifactId>spring-boot-logging-log4j2</artifactId>
|
||||
<name>spring-boot-logging-log4j2</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Demo project for Spring Boot Logging with Log4J2</description>
|
||||
|
||||
<!-- this needs to use the boot parent directly in order to not inherit logback dependencies -->
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.2.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- for Graylog demo -->
|
||||
<dependency>
|
||||
<!-- forcing spring boot 1.x sing log4j was dropped in spring boot 1.4 and beyond -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j</artifactId>
|
||||
<version>${spring-boot-starter-log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graylog2</groupId>
|
||||
<artifactId>gelfj</artifactId>
|
||||
<version>${gelfj.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkCount>3</forkCount>
|
||||
<reuseForks>true</reuseForks>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*IntTest.java</exclude>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<start-class>com.baeldung.springbootlogging.SpringBootLoggingApplication</start-class>
|
||||
<spring-boot-starter-log4j.version>1.3.8.RELEASE</spring-boot-starter-log4j.version>
|
||||
<gelfj.version>1.1.16</gelfj.version>
|
||||
<lombok.version>1.18.4</lombok.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.graylog;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class GraylogDemoApplication {
|
||||
|
||||
private final static Logger LOG =
|
||||
Logger.getLogger(GraylogDemoApplication.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GraylogDemoApplication.class, args);
|
||||
LOG.info("Hello from Spring Boot");
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.springbootlogging;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class LoggingController {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(LoggingController.class);
|
||||
|
||||
@GetMapping("/")
|
||||
public String index() {
|
||||
logger.trace("A TRACE Message");
|
||||
logger.debug("A DEBUG Message");
|
||||
logger.info("An INFO Message");
|
||||
logger.warn("A WARN Message");
|
||||
logger.error("An ERROR Message");
|
||||
|
||||
return "Howdy! Check out the Logs to see the output...";
|
||||
}
|
||||
|
||||
private static final org.apache.logging.log4j.Logger loggerNative = LogManager.getLogger(LoggingController.class);
|
||||
|
||||
@GetMapping("/native")
|
||||
public String nativeLogging() {
|
||||
loggerNative.trace("This TRACE message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.debug("This DEBUG message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.info("This INFO message has been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.warn("This WARN message been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.error("This ERROR message been printed by Log4j2 without passing through SLF4J");
|
||||
loggerNative.fatal("This FATAL message been printed by Log4j2 without passing through SLF4J");
|
||||
return "Howdy! Check out the Logs to see the output printed directly through Log4j2...";
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.springbootlogging;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
//import lombok.extern.log4j.Log4j2;
|
||||
//import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
@RestController("LombokLoggingController")
|
||||
@Slf4j
|
||||
// @CommonsLog (Comment any other Lombok logging annotation and uncomment this
|
||||
// to work with Apache Commons Logging)
|
||||
// @Log4j2 (Comment any other Lombok logging annotation and uncomment this to
|
||||
// work directly with Log4j2)
|
||||
public class LombokLoggingController {
|
||||
|
||||
@GetMapping("/lombok")
|
||||
public String index() {
|
||||
log.trace("A TRACE Message");
|
||||
log.debug("A DEBUG Message");
|
||||
log.info("An INFO Message");
|
||||
log.warn("A WARN Message");
|
||||
log.error("An ERROR Message");
|
||||
return "Howdy! Check out the Logs to see the output...";
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.springbootlogging;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBootLoggingApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootLoggingApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
|
||||
<log4j:configuration>
|
||||
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%t] --- %-40.40logger{39} : %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
<appender name="graylog" class="org.graylog2.log.GelfAppender">
|
||||
<param name="graylogHost" value="18.217.253.212"/>
|
||||
<param name="originHost" value="localhost"/>
|
||||
<param name="graylogPort" value="12201"/>
|
||||
<param name="extractStacktrace" value="true"/>
|
||||
<param name="addExtendedInformation" value="true"/>
|
||||
<param name="facility" value="log4j"/>
|
||||
<param name="Threshold" value="DEBUG"/>
|
||||
<param name="additionalFields" value="{'environment': 'DEV', 'application': 'GraylogDemoApplication'}"/>
|
||||
</appender>
|
||||
<root>
|
||||
<priority value="DEBUG"/>
|
||||
<appender-ref ref="stdout"/>
|
||||
<appender-ref ref="graylog"/>
|
||||
</root>
|
||||
</log4j:configuration>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration>
|
||||
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout
|
||||
pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
|
||||
</Console>
|
||||
|
||||
<RollingFile name="RollingFile"
|
||||
fileName="./logs/spring-boot-logger-log4j2.log"
|
||||
filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
|
||||
<PatternLayout>
|
||||
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
|
||||
</PatternLayout>
|
||||
<Policies>
|
||||
<!-- rollover on startup, daily and when the file reaches
|
||||
10 MegaBytes -->
|
||||
<OnStartupTriggeringPolicy />
|
||||
<SizeBasedTriggeringPolicy
|
||||
size="10 MB" />
|
||||
<TimeBasedTriggeringPolicy />
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<!-- LOG everything at INFO level -->
|
||||
<Root level="info">
|
||||
<AppenderRef ref="Console" />
|
||||
<AppenderRef ref="RollingFile" />
|
||||
</Root>
|
||||
|
||||
<!-- LOG "com.baeldung*" at TRACE level -->
|
||||
<Logger name="com.baeldung" level="trace"></Logger>
|
||||
</Loggers>
|
||||
|
||||
</Configuration>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.springbootlogging.SpringBootLoggingApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringBootLoggingApplication.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
## Spring Boot Nashorn
|
||||
|
||||
This module contains articles about Spring Boot with Nashorn
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Isomorphic Application with React and Nashorn](https://www.baeldung.com/react-nashorn-isomorphic-app)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?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.nashorn</groupId>
|
||||
<artifactId>spring-boot-nashorn</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>spring-boot-nashorn</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.nashorn;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(Application.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.nashorn.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class MyRestController {
|
||||
|
||||
@RequestMapping("/next/{last}/{secondLast}")
|
||||
public int index(@PathVariable("last") int last, @PathVariable("secondLast") int secondLast) throws Exception {
|
||||
return last + secondLast;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.nashorn.controller;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class MyWebController {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String index(Map<String, Object> model) throws Exception {
|
||||
|
||||
ScriptEngine nashorn = new ScriptEngineManager().getEngineByName("nashorn");
|
||||
|
||||
getClass().getResource("classpath:storedProcedures.sql");
|
||||
|
||||
nashorn.eval(new InputStreamReader(new ClassPathResource("static/js/react.js").getInputStream()));
|
||||
nashorn.eval(new InputStreamReader(new ClassPathResource("static/js/react-dom-server.js").getInputStream()));
|
||||
|
||||
nashorn.eval(new InputStreamReader(new ClassPathResource("static/app.js").getInputStream()));
|
||||
Object html = nashorn.eval("ReactDOMServer.renderToString(" + "React.createElement(App, {data: [0,1,1]})" + ");");
|
||||
|
||||
model.put("content", String.valueOf(html));
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
spring.mvc.view.prefix: /WEB-INF/jsp/
|
||||
spring.mvc.view.suffix: .jsp
|
||||
@@ -0,0 +1,37 @@
|
||||
var App = React.createClass({displayName: "App",
|
||||
|
||||
handleSubmit: function () {
|
||||
var last = this.state.data[this.state.data.length-1];
|
||||
var secondLast = this.state.data[this.state.data.length-2];
|
||||
$.ajax({
|
||||
url: '/next/'+last+'/'+secondLast,
|
||||
dataType: 'text',
|
||||
success: function (msg) {
|
||||
var series = this.state.data;
|
||||
series.push(msg);
|
||||
this.setState({data: series});
|
||||
}.bind(this),
|
||||
error: function (xhr, status, err) {
|
||||
console.error("/next", status, err.toString());
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.setState({data: this.props.data});
|
||||
},
|
||||
|
||||
getInitialState: function () {
|
||||
return {data: []};
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return (
|
||||
React.createElement("div", {className: "app"},
|
||||
React.createElement("h2", null, "Fibonacci Generator"),
|
||||
React.createElement("h2", null, this.state.data.toString()),
|
||||
React.createElement("input", {type: "submit", value: "Next", onClick: this.handleSubmit})
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* ReactDOMServer v0.14.3
|
||||
*
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||
;(function(f) {
|
||||
// CommonJS
|
||||
if (typeof exports === "object" && typeof module !== "undefined") {
|
||||
module.exports = f(require('react'));
|
||||
|
||||
// RequireJS
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(['react'], f);
|
||||
|
||||
// <script>
|
||||
} else {
|
||||
var g
|
||||
if (typeof window !== "undefined") {
|
||||
g = window;
|
||||
} else if (typeof global !== "undefined") {
|
||||
g = global;
|
||||
} else if (typeof self !== "undefined") {
|
||||
g = self;
|
||||
} else {
|
||||
// works providing we're not in "use strict";
|
||||
// needed for Java 8 Nashorn
|
||||
// see https://github.com/facebook/react/issues/3037
|
||||
g = this;
|
||||
}
|
||||
g.ReactDOMServer = f(g.React);
|
||||
}
|
||||
|
||||
})(function(React) {
|
||||
return React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
});
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* ReactDOM v0.14.3
|
||||
*
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||
;(function(f) {
|
||||
// CommonJS
|
||||
if (typeof exports === "object" && typeof module !== "undefined") {
|
||||
module.exports = f(require('react'));
|
||||
|
||||
// RequireJS
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(['react'], f);
|
||||
|
||||
// <script>
|
||||
} else {
|
||||
var g
|
||||
if (typeof window !== "undefined") {
|
||||
g = window;
|
||||
} else if (typeof global !== "undefined") {
|
||||
g = global;
|
||||
} else if (typeof self !== "undefined") {
|
||||
g = self;
|
||||
} else {
|
||||
// works providing we're not in "use strict";
|
||||
// needed for Java 8 Nashorn
|
||||
// see https://github.com/facebook/react/issues/3037
|
||||
g = this;
|
||||
}
|
||||
g.ReactDOM = f(g.React);
|
||||
}
|
||||
|
||||
})(function(React) {
|
||||
return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
});
|
||||
+18794
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello React!</title>
|
||||
<script type="text/javascript" src="js/react.js"></script>
|
||||
<script type="text/javascript" src="js/react-dom.js"></script>
|
||||
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">${content}</div>
|
||||
<script type="text/javascript" src="app.js"></script>
|
||||
<script type="text/javascript">
|
||||
ReactDOM.render(
|
||||
React.createElement(App, {data: [0,1,1]}),
|
||||
document.getElementById("root")
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
## Spring Boot Performance
|
||||
|
||||
This module contains articles about Spring Boot performance.
|
||||
|
||||
### Relevant Articles
|
||||
|
||||
- [Lazy Initialization in Spring Boot 2](https://www.baeldung.com/spring-boot-lazy-initialization)
|
||||
@@ -1,45 +0,0 @@
|
||||
<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>
|
||||
<artifactId>spring-boot-performance</artifactId>
|
||||
<name>spring-boot-performance</name>
|
||||
<packaging>war</packaging>
|
||||
<description>This is a simple Spring Boot application taking advantage of the latest Spring Boot improvements/features. Current version: 2.2</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-boot-performance</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<!-- The main class to start by executing java -jar -->
|
||||
<start-class>com.baeldung.lazyinitialization.Application</start-class>
|
||||
</properties>
|
||||
</project>
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package com.baeldung.lazyinitialization;
|
||||
|
||||
import com.baeldung.lazyinitialization.services.Writer;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
@Bean("writer1")
|
||||
public Writer getWriter1() {
|
||||
return new Writer("Writer 1");
|
||||
}
|
||||
|
||||
@Bean("writer2")
|
||||
public Writer getWriter2() {
|
||||
return new Writer("Writer 2");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ApplicationContext ctx = SpringApplication.run(Application.class, args);
|
||||
System.out.println("Application context initialized!!!");
|
||||
|
||||
Writer writer1 = ctx.getBean("writer1", Writer.class);
|
||||
writer1.write("First message");
|
||||
|
||||
Writer writer2 = ctx.getBean("writer2", Writer.class);
|
||||
writer2.write("Second message");
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package com.baeldung.lazyinitialization.services;
|
||||
|
||||
public class Writer {
|
||||
|
||||
private final String writerId;
|
||||
|
||||
public Writer(String writerId) {
|
||||
this.writerId = writerId;
|
||||
System.out.println(writerId + " initialized!!!");
|
||||
}
|
||||
|
||||
public void write(String message) {
|
||||
System.out.println(writerId + ": " + message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
spring:
|
||||
main:
|
||||
lazy-initialization: true
|
||||
Reference in New Issue
Block a user