I'm working on my new Java + Spring + Thymeleaf project. So today I've got a very strange message from thymeleaf:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'session' available as request attribute
You know, it is really strange. According to thymeleaf documentation https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html (chapter 3):
Similarly to the request parameters, session attributes can be access by using the session. prefix:
<p th:text="${session.mySessionAttribute}" th:unless="${session == null}">[...]</p>
So, ok. I've tried another way:
Or by using #session, that gives you direct access to the javax.servlet.http.HttpSession object: ${#session.getAttribute('mySessionAttribute')}
And got the exception:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name '#session' available as request attribute
I didn't find any solutions of this problem on google. So, it's time to show you some code. Controller mapping:
@Controller
@RequestMapping("/admin")
public class AdminController {
@GetMapping("/addPost")
public String addPost(HttpSession session, Model model) {
session.setAttribute("post", new Post());
return "admin/add-post";
}
@PostMapping("/addPost")
public String processAddPost(HttpSession session) {
Post post = (Post)session.getAttribute("post");
try {
postService.addPost(post);
} catch (Exception ignore) {}
session.removeAttribute("post");
return "redirect:/admin/listPosts";
}
...
}
Piece of HTML page(displayed on GET request to /admin/addPost):
<form
th:action="@{/admin/previewPost}"
th:object="${session.post}"
method="post">
<input
id="post_name_input"
placeholder="Post name"
th:field="*{name}" />
<br>
<textarea
id="post_description_textarea"
class="wide-input"
placeholder="Post content"
th:field="*{description}" />
<br>
<button type="submit">Create</button>
</form>
What am I doing wrong? Maybe, there is a bug in thymeleaf? My build.gradle:
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-tomcat-plugin:2.4.1'
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'com.bmuschko.tomcat'
compileJava.options.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
def tomcatVersion = '9.0.22'
dependencies {
testImplementation 'junit:junit:4.12'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.2",
"org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.8.4'
}
tomcat {
httpProtocol = 'org.apache.coyote.http11.Http11Nio2Protocol'
ajpProtocol = 'org.apache.coyote.ajp.AjpNio2Protocol'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.apache.tomcat:tomcat-dbcp:9.0.22'
implementation 'org.postgresql:postgresql:42.2.6'
implementation 'org.springframework:spring-context:5.1.8.RELEASE'
implementation 'org.springframework:spring-webmvc:5.1.8.RELEASE'
implementation 'org.springframework:spring-orm:5.1.8.RELEASE'
implementation 'org.springframework:spring-tx:5.1.8.RELEASE'
implementation 'org.springframework:spring-aspects:5.1.8.RELEASE'
implementation 'org.hibernate:hibernate-core:5.4.1.Final'
implementation 'org.springframework.security:spring-security-core:5.1.5.RELEASE'
implementation 'org.springframework.security:spring-security-web:5.1.5.RELEASE'
implementation 'org.springframework.security:spring-security-config:5.1.5.RELEASE'
implementation 'org.springframework.data:spring-data-jpa:2.1.10.RELEASE'
implementation 'javax.servlet:servlet-api:2.5'
implementation 'org.hibernate.validator:hibernate-validator:6.0.2.Final'
implementation 'org.hibernate.validator:hibernate-validator-annotation-processor:6.0.2.Final'
implementation 'org.thymeleaf:thymeleaf:3.0.11.RELEASE'
implementation 'org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE'
implementation 'org.aspectj:aspectjrt:1.5.4'
implementation 'org.apache.logging.log4j:log4j-api:2.8.2'
implementation 'org.apache.logging.log4j:log4j-core:2.8.2'
}
UPD: This answer was marked as duplicated. But it is not. I've tried all solutions in the referenced question and they didn't work for me. The main difference is that it seems in my case there is no 'session' object in thymeleaf context.