Skip to content

Commit

Permalink
Merge pull request #37 from wimdeblauwe/feature/spring-6-boot-3
Browse files Browse the repository at this point in the history
Support Spring Boot 3 with Spring Framework 6 and Thymeleaf 3.1
  • Loading branch information
wimdeblauwe authored Dec 1, 2022
2 parents 6c57984 + 815a1a4 commit 6fcc1c4
Show file tree
Hide file tree
Showing 17 changed files with 65 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
name: "Build with ${{ matrix.java }}"
strategy:
matrix:
java: [ 11 ]
java: [ 17 ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Set up JDK 11
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'

- name: Cache local Maven repository
uses: actions/cache@v3
Expand All @@ -30,7 +30,7 @@ jobs:
uses: actions/setup-java@v3
with: # running setup-java again overwrites the settings.xml
distribution: 'temurin'
java-version: 11
java-version: 17
server-id: ossrh
server-username: OSSRH_USERNAME
server-password: OSSRH_PASSWORD
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ public SecurityFilterChain filterChain(HttpSecurity http)throws Exception{
}
```

## Spring Boot compatibility

| htmx-spring-boot-thymeleaf | Spring Boot | Minimum Java version |
| -------------------------- | ----------- | -------------------- |
| [2.0.0](https://github.com/wimdeblauwe/htmx-spring-boot-thymeleaf/releases/tag/2.0.0) | 3.0.x | 17 |
| [1.0.0](https://github.com/wimdeblauwe/htmx-spring-boot-thymeleaf/releases/tag/1.0.0) | 2.7.x | 11 |


## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Expand Down
14 changes: 8 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<version>3.0.0</version>
<relativePath/>
</parent>
<groupId>io.github.wimdeblauwe</groupId>
<artifactId>htmx-spring-boot-thymeleaf</artifactId>
<version>1.0.0</version>
<version>2.0.0-SNAPSHOT</version>
<name>Spring Boot and Thymeleaf library for htmx</name>
<description>Spring Boot library to make it easy to work with htmx and Thymeleaf</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<java.version>17</java.version>

<maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
<jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
</properties>
<licenses>
<license>
Expand Down Expand Up @@ -101,7 +102,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[${java.version}, 12)</version>
<version>[${java.version}, 18)</version>
</requireJavaVersion>
</rules>
</configuration>
Expand All @@ -125,6 +126,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<executions>
<execution>
<id>jacoco-prepare</id>
Expand Down Expand Up @@ -210,7 +212,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[${java.version}, 12)</version>
<version>[${java.version}, 18)</version>
</requireJavaVersion>
</rules>
</configuration>
Expand All @@ -219,7 +221,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<source>8</source>
<source>${java.version}</source>
<detectJavaApiLink>false</detectJavaApiLink>
</configuration>
<executions>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.wimdeblauwe.hsbt.mvc;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

import static io.github.wimdeblauwe.hsbt.mvc.HtmxResponseHeader.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package io.github.wimdeblauwe.hsbt.mvc;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

import java.util.Objects;

import static io.github.wimdeblauwe.hsbt.mvc.HtmxRequestHeader.*;
Expand All @@ -23,36 +22,38 @@ public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
Object nativeRequest = webRequest.getNativeRequest();
System.out.println("nativeRequest = " + nativeRequest);
return createHtmxRequest(Objects.requireNonNull(webRequest.getNativeRequest(HttpServletRequest.class)));
}

public static HtmxRequest createHtmxRequest(HttpServletRequest req) {
String hxRequestHeader = req.getHeader(HX_REQUEST.getValue());
public static HtmxRequest createHtmxRequest(HttpServletRequest request) {
String hxRequestHeader = request.getHeader(HX_REQUEST.getValue());
if (hxRequestHeader == null) {
return new HtmxRequest.Builder(false).build();
}

HtmxRequest.Builder builder = new HtmxRequest.Builder(true);
if (req.getHeader(HX_BOOSTED.getValue()) != null) {
if (request.getHeader(HX_BOOSTED.getValue()) != null) {
builder.withBoosted(true);
}
if (req.getHeader(HX_CURRENT_URL.getValue()) != null) {
builder.withCurrentUrl(req.getHeader(HX_CURRENT_URL.getValue()));
if (request.getHeader(HX_CURRENT_URL.getValue()) != null) {
builder.withCurrentUrl(request.getHeader(HX_CURRENT_URL.getValue()));
}
if (req.getHeader(HX_HISTORY_RESTORE_REQUEST.getValue()) != null) {
if (request.getHeader(HX_HISTORY_RESTORE_REQUEST.getValue()) != null) {
builder.withHistoryRestoreRequest(true);
}
if (req.getHeader(HX_PROMPT.getValue()) != null) {
builder.withPromptResponse(req.getHeader(HX_PROMPT.getValue()));
if (request.getHeader(HX_PROMPT.getValue()) != null) {
builder.withPromptResponse(request.getHeader(HX_PROMPT.getValue()));
}
if (req.getHeader(HX_TARGET.getValue()) != null) {
builder.withTarget(req.getHeader(HX_TARGET.getValue()));
if (request.getHeader(HX_TARGET.getValue()) != null) {
builder.withTarget(request.getHeader(HX_TARGET.getValue()));
}
if (req.getHeader(HX_TRIGGER_NAME.getValue()) != null) {
builder.withTriggerName(req.getHeader(HX_TRIGGER_NAME.getValue()));
if (request.getHeader(HX_TRIGGER_NAME.getValue()) != null) {
builder.withTriggerName(request.getHeader(HX_TRIGGER_NAME.getValue()));
}
if (req.getHeader(HX_TRIGGER.getValue()) != null) {
builder.withTriggerId(req.getHeader(HX_TRIGGER.getValue()));
if (request.getHeader(HX_TRIGGER.getValue()) != null) {
builder.withTriggerId(request.getHeader(HX_TRIGGER.getValue()));
}
return builder.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package io.github.wimdeblauwe.hsbt.mvc;

import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;

import java.util.List;

@Configuration(proxyBeanMethods = false)
@AutoConfiguration
@ConditionalOnWebApplication
public class HtmxMvcConfiguration implements WebMvcRegistrations, WebMvcConfigurer {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.github.wimdeblauwe.hsbt.mvc;

import jakarta.servlet.http.HttpServletRequest;
import org.thymeleaf.context.IExpressionContext;
import org.thymeleaf.context.IWebContext;
import org.thymeleaf.expression.IExpressionObjectFactory;
import org.thymeleaf.spring5.expression.*;
import org.thymeleaf.web.IWebExchange;
import org.thymeleaf.web.servlet.IServletWebRequest;

import java.util.Collections;
import java.util.LinkedHashSet;
Expand All @@ -29,8 +31,10 @@ public Set<String> getAllExpressionObjectNames() {
}

public Object buildObject(final IExpressionContext context, final String expressionObjectName) {
if (HTMX_REQUEST_EXPRESSION_OBJECT_NAME.equals(expressionObjectName) && context instanceof IWebContext) {
return HtmxHandlerMethodArgumentResolver.createHtmxRequest(((IWebContext) context).getRequest());
if (HTMX_REQUEST_EXPRESSION_OBJECT_NAME.equals(expressionObjectName) && context instanceof IWebContext webContext) {
IWebExchange exchange = webContext.getExchange();
IServletWebRequest request = (IServletWebRequest) exchange.getRequest();
return HtmxHandlerMethodArgumentResolver.createHtmxRequest((HttpServletRequest) request.getNativeRequestObject());
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
package io.github.wimdeblauwe.hsbt.mvc;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.util.Assert;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.wimdeblauwe.hsbt.security;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.spring5.requestdata.RequestDataValueProcessorUtils;
import org.thymeleaf.spring6.requestdata.RequestDataValueProcessorUtils;
import org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor;
import org.thymeleaf.standard.util.StandardProcessorUtils;
import org.thymeleaf.templatemode.TemplateMode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.github.wimdeblauwe.hsbt.thymeleaf;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AutoConfiguration
@ConditionalOnWebApplication
public class HtmxThymeleafConfiguration {
@Bean
Expand Down
6 changes: 0 additions & 6 deletions src/main/resources/META-INF/spring.factories

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
io.github.wimdeblauwe.hsbt.thymeleaf.HtmxThymeleafConfiguration
io.github.wimdeblauwe.hsbt.mvc.HtmxMvcConfiguration
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
io.github.wimdeblauwe.hsbt.thymeleaf.HtmxThymeleafConfiguration
io.github.wimdeblauwe.hsbt.mvc.HtmxMvcConfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ public void testPostTodo() throws Exception {
public void testHtmxRequestExpressionUtility() throws Exception {
mockMvc.perform(get("/partials/expressionUtility").header("HX-Request", "true"))
.andExpect(status().isOk())
.andExpect(xpath("//div[@id='htmxRequest']").exists())
.andExpect(xpath("//div[@id='webRequest']").exists());
.andExpect(xpath("//div[@id='htmxRequest']").exists());
}

@Test
Expand Down
3 changes: 1 addition & 2 deletions src/test/resources/templates/htmxRequest.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
<title>htmx request</title>
</head>
<body>
<!--/*@thymesVar id="#htmxRequest" type="HtmxRequest"*/-->
<div id="webRequest" th:if="${#request.getHeader('HX-Request')}">It is an htmx Request using the underlying request</div>
<!--/*@thymesVar id="#htmxRequest" type="io.github.wimdeblauwe.hsbt.mvc.HtmxRequest"*/-->
<div id="htmxRequest" th:if="${#htmxRequest.isHtmxRequest()}">It is an htmx Request</div>

</body>
Expand Down

0 comments on commit 6fcc1c4

Please sign in to comment.