## Der Teufel steckt im Detail
-```
+```javascript
/** Optimierte Methoden für die Werbe-Einblendung via OpenX */
/** see: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/ */
## Release notes:
-```
+```text
commit 4b507b15b0122ac180e44b8418db8d9143ae9c3a
Author: Kai Moritz
Date: Tue Jan 15 23:09:01 2013 +0100
## Release notes:
-```
+```text
commit 4edef457d2b747d939a141de24bec5e32abbc0c7
Author: Kai Moritz
Date: Fri Aug 2 00:37:40 2013 +0200
## Release notes:
-```
+```text
commit adb20bc4da63d4cec663ca68648db0f808e3d181
Author: Kai Moritz
Date: Fri Oct 18 01:52:27 2013 +0200
## Release notes:
-```
+```text
commit f3dabc0e6e3676244986b5bbffdb67d427c8383c
Author: Kai Moritz
Date: Mon Jun 2 10:31:12 2014 +0200
## Release notes:
-```
+```text
commit ec30af2068f2d12a9acf65474ca1a4cdc1aa7122
Author: Kai Moritz
Date: Tue Nov 11 15:28:12 2014 +0100
I often violate that rule, when developing templates for dynamically rendered pages with [Thymeleaf](http://www.thymeleaf.org/ "Read more about the XML/XHTML/HTML5 template engine Thymeleaf"), or similar techniques.
That is, because I like to place the template-files on a subdirectory of the directory, that contains my webapp ( `src/main/webapp` with Maven):
-```
+```text
+ src/main/webapp/
+ css/
+ img/
## Release notes:
-```
+```text
commit 94e6b2e93fe107e75c9d20aa1eb3126e78a5ed0a
Author: Kai Moritz
Date: Sat May 16 14:14:44 2015 +0200
The code for this.logging.level.de.juplo.yourshouter= part is tagged with `part-00`.
Appart from the HTML-templates, the attic for spring-boot and the build-definitions in the `pom.xml` it mainly consists of one file:
-```Java
+```java
@Controller
@RequestMapping("/")
public class HomeController
The following class rebuilds the same configuration explicitly:
-```Java
+```java
@Configuration
@EnableSocial
public class SocialConfig extends SocialConfigurerAdapter
Attentive readers might have noticed, that we have configured such a source, when we were [explicitly rebuilding](/develop-a-facebook-app-with-spring-social-part-01-behind-the-scenes/ "Jump back to re-read our explicitly rebuild configuration") the automatic default-configuration of Spring Boot:
-```Java
+```java
public class AnonymousUserIdSource implements UserIdSource
{
@Override
The implementation of `ConnectionSignUp` simply uses the ID, that is provided by the social network.
Since we are only signing in users from Facebook, these ID's are guaranteed to be unique.
-```Java
+```java
public class ProviderUserIdConnectionSignUp implements ConnectionSignUp
{
@Override
The implementation of `UserIdSource` retrieves the ID, that was stored in the `SecurityContext` (our simple implementation — not to be confused with the class from Spring Security).
If no user is stored in the `SecurityContext`, it falls back to the old behavior and returns the fix id `anonymous`.
-```Java
+```java
public class SecurityContextUserIdSource implements UserIdSource
{
private final static Logger LOG =
To replace the `AnonymousUserIdSource` by our new implementation, we simply instantiate that instead of the old one in our configuration-class `SocialConfig`:
-```Java
+```java
@Override
public UserIdSource getUserIdSource()
{
There are several ways to plug in the `ConnectionSignUp`.
I decided, to plug it into the instance of `InMemoryUsersConnectionRepository`, that our configuration uses, because this way, the user will be signed up automatically on sign in, if it is not known to the application:
-```Java
+```java
@Override
public UsersConnectionRepository getUsersConnectionRepository(
ConnectionFactoryLocator connectionFactoryLocator
This enables us, to be aware of that event and remember the user for subsequent calls.
Our implementation stores the user in our `SecurityContext` to sign him in and creates a cookie to remember him for subsequent calls:
-```Java
+```java
public class UserCookieSignInAdapter implements SignInAdapter
{
private final static Logger LOG =
To enable the Sign-In, we have to plug our `SignInAdapter` into the `ProviderSignInController`:
-```Java
+```java
@Bean
public ProviderSignInController signInController(
ConnectionFactoryLocator factoryLocator,
We refine the method `preHandle`, so that it redirects every request to our sign-in-page, that is not authenticated:
-```Java
+```java
@Override
public boolean preHandle(
HttpServletRequest request,
As it is now not possible, to call any page except the sigin-up-page, without beeing redirected to our sign-in-page, if you are not authenticated, it is impossible to call any page without being authenticated.
Hence, we can (and should!) refine our `UserIdSource`, to throw an exception, if that happens anyway, because it has to be a sign for a bug:
-```Java
+```java
public class SecurityContextUserIdSource implements UserIdSource
{
To actually enable the [automatic handling](https://developers.facebook.com/docs/games/gamesonfacebook/login#usingsignedrequest "Read about all the cumbersome steps, that would be necesarry, if you had to handle a signed_requst by yourself") of the `signed_request`, that is, decoding the `signed_request` and sign in the user with the data provided in the `signed_request`, you just have to add the `CanvasSignInController` as a bean in your `SocialConfig`:
-```Java
+```java
@Bean
public CanvasSignInController canvasSignInController(
ConnectionFactoryLocator connectionFactoryLocator,
To achieve that, we have to refine our [`UserCookieInterceptor`](/develop-a-facebook-app-with-spring-social-part-05-refactor-the-redirect-logic#redirect "Compare the changes to the unchanged method of our UserCookieInterceptor") as follows.
First add a pattern for all pages, that are allowed to be accessed unauthenticated:
-```Java
+```java
private final static Pattern PATTERN = Pattern.compile("^/signin|canvas");
```
Then match the requests against this pattern, instead of the fixed string `/signin`:
-```Java
+```java
if (PATTERN.matcher(request.getServletPath()).find())
return true;
To siwtch from the default client, that comes with the JDK to Apaches `HttpClient`, you have to configure an instance of `HttpComponentsClientHttpRequestFactory` as `HttpRequestFactory` in your `SocialConfig`:
-```Java
+```java
@Bean
public HttpComponentsClientHttpRequestFactory requestFactory(Environment env)
{
## Release notes:
-```
+```text
commit 64b7446c958efc15daf520c1ca929c6b8d3b8af5
Author: Kai Moritz
Date: Tue Mar 8 00:25:50 2016 +0100
Browsing the URL of the app resulted in a 404.
And instead of [the fancy Spring-Boot ASCII-art banner](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html "See, what Spring-Boot usually shows, when starting..."), the only matching entry that showed up in my log-file was:
-```Bash
+```log
INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Spring WebApplicationInitializers detected on classpath: [org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JerseyWebApplicationInitializer@1fe086c]
```
For example, the XPath-expression
-```XPath
+```text
//child/ref[ancestor::parent/ref=.]
```
will match the `<ref>`-node with `@id='bar'`, that is nested insiede the `<child>`-node in this example-XML, what I was not expecting:
-```Java
+```xml
<root>
<parent>
<ref id="foo"><content>Same Text-Content</content></ref>
So, what I tried, after I found out about `deep-equal()` was the following `Xpath`-expression, which solves the problem in the above example:
-```XPath
+```text
//child/ref[deep-equal(ancestor::parent/ref,.)]
```
But, moving on I stumbled accross cases, where I was expecting a match, but `deep-equal()` does not match the nodes.
For example:
-```Java
+```xml
<root>
<parent>
<ref id="same">
1. Specifiy the dependency for Spring Boot Actuator:
- ```
+ ```xml
<dependency>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter-actuator
The simple fix for this problem is, to add a `@Bean` of type `InMemoryHttpTraceRepository` to your **`@Configuration`**-class:
-```
+```java
@Bean
public HttpTraceRepository htttpTraceRepository()
{
Resending the messages in correct order after a failure (or downtime) is no problem.
But some of the messages may be send twice (or more often), because the producer does not know exactly, which messages were send successful.
-```
+```text
Incident A - { id: 1, data: "ab583cc8f8" }
Incident B - { id: 2, data: "83ccc8f8f8" }
Incident C - { id: 3, data: "115tab5b58" }
In this simplified setup, the implementation effectively boils down to the following method-override:
-```
+```java
@Override
public Iterable<String> transform(String value)
{
We can use our `ValueTransformer` with **`flatTransformValues()`**,
to let Kafka Streams drop the detected duplicate values:
-```
+```java
streamsBuilder
.stream("input")
.flatTransformValues(
Additionally Beans can be added programatically very easy with the help of an `ApplicationContextInitializer`:
-```
+```java
@AllArgsConstructor
public class MultipleBeansApplicationContextInitializer
implements
If you write an **`EnvironmentPostProcessor`**, you will get access to an instance of `ConfigurableEnvironment`, that contains a complete list of all `PropertySource`'s, that are configured for your Spring-Boot-App.
-```
+```java
public class MultipleBeansEnvironmentPostProcessor
implements
EnvironmentPostProcessor
Finally, you have to [register](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-customize-the-environment-or-application-context "Read more on details and/or alternatives of the mechanism") the `EnvironmentPostProcessor` with your Spring-Boot-App.
This is done in the **`META-INF/spring.factories`**:
-```
+```properties
org.springframework.boot.env.EnvironmentPostProcessor=\
de.juplo.demos.multiplebeans.MultipleBeansEnvironmentPostProcessor
```
On Linux/Unix this can be simply done by editing **`/etc/hosts`**.
You just have to add the domain ( `example.com`) at the end of the line that starts with `127.0.0.1`:
-```hosts
+```text
127.0.0.1 localhost example.com
```
Consider the following controller, that defines a request-handling and an accompanying exception-handler, for an
`IllegalArgumentException`, that may by thrown in the business-logic:
-```
+```java
@Controller
public class ExampleController
{
With the help of `@WebMvcTest`, we can easily mock away the actual implementation of the business-logic and concentrate on the code under test:
our specialized exception-handler.
-```
+```java
@WebMvcTest(ExampleController.class)
class ExceptionHandlingApplicationTests
{
Location: http://localhost:8080/users/peter
```
- Requests to registrate an already existing user will result in a 400 (Bad Request):
- ```
+ ```shellsession
$ echo peter | http :8080/users
HTTP/1.1 400
Date: Fri, 05 Feb 2021 14:44:53 GMT
```
- Successfully registrated users can be listed:
- ```
+ ```shellsession
$ http :8080/users
HTTP/1.1 200
The event takes a key ( `username`) and an object as value (an instance of an enum in our case).
An `EventListener` receives the events and writes them in the outbox table:
-```
+```java
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void onUserEvent(OutboxEvent event)
{