Persist Spring Session without Spring Security - spring-boot

I am seeking assistance in configuring Spring Boot to persist a Spring Session without using Spring Security.
I started with the HttpSession JDBC Spring Boot sample app, to persist a Spring Session for a Spring Boot app. However this uses Spring Security. When removing Spring Security, the session ceases to be persisted in the H2 database. The XML config and Java config sample apps do not utilize Spring Security. Thus, not a requirement.
The guide states that the springSessionRepositoryFilter will create the Spring Session. However, after removing Spring Security and debugging this filter (SessionRepositoryFilter), the boolean passed to SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(boolean) is never set to true. Thus, the Spring Session is never created and persisted.
Any suggestions on additional configuration required to persist a Spring Session for a Spring Boot app, without Spring Security?
Here are the relevant classes, pom.xml, and application.property file:
#SpringBootApplication
public class SbWebSessionJdbcApplication {
public static void main(String[] args) {
SpringApplication.run(SbWebSessionJdbcApplication.class, args);
}
}
#EnableJdbcHttpSession
public class HttpSessionConfig {
}
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</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>
</plugin>
</plugins>
</build>
application.properties
spring.thymeleaf.cache=false
spring.template.cache=false
spring.datasource.schema=classpath:org/springframework/session/jdbc/schema-h2.sql
spring.h2.console.enabled=true
logging.level.org.springframework.web=DEBUG

Actually, there isn't anything more in particular you need to configure - you just need to initiate the creation of HttpSession and use it according to your needs. For example, the simplest way to achieve this would be to have Spring MVC controller method with HttpSession as an argument.
Check out this repo on Github, in particular basic-jdbc module. It's exactly the sample you're looking for - Spring Boot application with Spring Session but without Spring Security.

Related

http_client_requests_seconds_count missing in spring boot promethus endpoint

I am trying to enable Prometheus endpoint in my springboot project having below dependencies.
SpringBoot version:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.12-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
I am using restTemplate to make outbound call but when i check Prometheus endpoint, the data related with http_client_requests_* are missing
Application properties:
management.endpoints.web.exposure.include=health,metrics,prometheus
management.endpoint.health.show-details=always
management.endpoint.health.enabled=true
management.endpoint.info.enabled=true
management.metrics.web.server.request.autotime.percentiles=0.90,0.95
management.metrics.web.client.request.autotime.percentiles=0.90,0.95
management.metrics.web.client.request.autotime.enabled=true
Just ensure you create your RestTemplate as a spring managed bean to ensure it gets a chance for instrumentation (if not auto created). You can customise with RestTemplateBuilder, and then inject it into the place you need like any other Spring bean.
#Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.additionalCustomizers(myRestTemplateCustomizer())
.build();
}
And you may also require
<!-- Micrometer core dependency -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
Manual creation (using 'new' within a class) is one cause for it to not link up to metrics.

How to set Log4j2 level from command line

I build a Spring Boot Web Service application and I am using Log4j2.
I want to set log level by passing something like: --log4j2.level=DEBUG - How can I do that?
I didn't found any documentation for it.
I know that I can set the log4j configuration file by --logging.config=/path/to/file but this is not what I want.
My pom.xml:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>...</name>
<description>...</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.25</version>
</dependency>
<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>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
My main class looks like:
#SpringBootApplication
#Log4j2
public class MyApplication {
public static void main(String[] args) {
log.debug("Test something");
SpringApplication.run(HlsManipulatorApplication.class, args);
}
}
Thanks for help!
Spring Boot applications initialize logging at least 3 times. The first is in SpringApplication when it creates a logger, which is literally the first thing that happens. If you are using Log4j 2 this will cause it to use its normal mechanism to find a log4j2.xml, log4j2.properties or log4j2.yml file. Spring boot provides a default configuration but as you know you can override it. If you do you can specify the root logger as
<Root level="${sys:root_log_level:-INFO}">
...
</Root>
This will allow you to use -Droot_log_level=DEBUG on the command line. If the system property is not configured it will default to INFO.
Note that you can also specify an alternate location for the logging configuration by a) specifying the location of the file in bootstrap.yml as
logging:
config: log4j2-myapp.xml
and then b) in a file named log4j2.application.properties as
log4j.configurationFile=log4j-mmyapp.xml
Doing this will cause the same configuration to be used each time Log4j reconfigures, including the initial configuration. You can see an example of this in Log4j's sample Spring Boot application where it retrieves the logging configuration from Spring Cloud Config.
Of course, you can utilize Spring's mechanism to set the logging level but that will not impact the first time logging is configured since Spring hasn't done anything at that point.
I should also point out that Log4j comes with a SpringLookup that can be used in Spring applications to reference spring configuration variables in the log4j configuration. Of course, the variables won't have a value the first time logging is configured since the Spring environment won't have been crea

How can we use Spring Cloud Sleuth with spring MVC project?

I am trying to use spring cloud sleuth with spring web mvc project. We are sending the request from spring web mvc to another spring boot project. I need to have the traceID and spanId to display in the UI. How can we achieve this?
EDIT
POM.xml for the spring boot application. I am using the latest version of Spring Boot and added the dependency of spring cloud sleuth.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Web MVC code: I am using spring rest template and calling the spring boot service from the spring web mvc application.
#Controller
public class HelloController {
#Autowired
RestTemplate restTemplate;
private Logger logger = Logger.getLogger(HelloController.class);
#GetMapping("/hello")
public String hello(Model model) {
logger.info("Hello from controller");
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8092/test", String.class);
String response = entity.getBody();
logger.info("Response from Service: "+ response);
model.addAttribute("name", "Test");
return "welcome";
}
}
In order to do that, you need to inject the Tracer bean and then if you call tracer.currentSpan().context().traceIdString() and tracer.currentSpan().context().spanIdString().

JSP Page not rendering in SpringBoot Application

I have seen lot of same problem but My problem is not resolving with all those solutions. My JSP page is not rendering.
I have added all required jars like thymeleaf, tomcat, jstl to run the application but still getting error
Below is my controller
#RequestMapping("/rest/user")
public class BookResource {
#GetMapping("/recommend")
public List<String> recommend() {
return bookrepo.BookDetail(bookname);
}
#RequestMapping(value = "/recommendation", method = RequestMethod.GET)
public String recommend(Model model) {
model.addAttribute("recommendations", bookrepo.BookDetail(bookname));
model.addAttribute("name", "Harsh");
return "recommendation";
}
}
After i Hit the URL I am getiing below error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue May 28 09:50:33 IST 2019
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template "recommendation", template might not exist or might not be accessible by any of the configured Template Resolvers
The JSP Page I have created not rendering, I put my jsp page inside resources/templates and also at WEB-INF/jsp/.
And properties file is also updated
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Pom.xml
<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.springBootApp</groupId>
<artifactId>FirstSpringBootApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-datepicker</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.9.1</version>
</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-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Redis Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</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-web</artifactId>
</dependency>
<!-- GCP Dependencies -->
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
<version>1.0.0.RELEASE</version>
</dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- GCP plugin -->
<!-- <plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin> -->
</plugins>
</build>
</project>
Structure .
As per spring boot there are Limitations when it comes to jsp's.
If packaging is not declared in pom.xml, spring boot by default considers it as jar.
To overcome these limitations we need to have the configuration made in the application to render jsp by placing the jsp's under src/main/resources/META-INF/resources/WEB-INF/jsp folder.
Sample Code: Click Here
References:
https://dzone.com/articles/spring-boot-with-jsps-in-executable-jars-1
https://github.com/hengyunabc/spring-boot-fat-jar-jsp-sample
Spring Boot does not support JSPs when using jar packaging. If you want to use JSPs then you must use war packaging. You can do that by adding the following to your pom.xml:
<packaging>war</packaging>
It's typically placed immediately after the line with the <version> tag.
Having made that change, you should tell Eclipse to update your Maven project by right-clicking FirstSpringBootApp and then selecting Maven -> Update Project….
Using war packaging will mean that src/main/webapp is recognised by Eclipse and your JSP files in src/main/webapp/WEB-INF/jsp should then be found. For further reference, Spring Boot has a sample project for JSPs that may be of interest.
In 2021 version, You need to add only tomcat jasper
dependency in pom.xml file to run the .jsp file in Spring boot application. Don't add jstl dependency, not highly required.
In application.properties file, you are required to add below code
spring.mvc.view.prefix=/folder name/
spring.mvc.view.suffix=.jsp
actually this is not required
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
because anyways tomcat server locate the jsp file.
It worked for me. 100% will work.
From your stacktrace it can be seen that springboot fails to resolve your template "recommendation", so it must have something to do with where you have kept your jsp files.
Keep your jsp templates under /WEB-INF/jsp/ since that's what you have provided in the application.properties. Also , ensure that the extension for your template is .jsp itself since you have specified that in property file as well.
Ensure that , in your pom you have the following dependencies added :
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- To compile JSP files -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
You can remove the thymeleaf dependency since you are using jsp as the templating engine here.
If that did not work, then you can try manually configuring your jsp view resolver like :
#Configuration
public class MvcConfiguration implements WebMvcConfigurer
{
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
registry.viewResolver(resolver);
}
}

How to set Hibernate bulk_id_strategy in spring boot application?

Hibernate is generating temporary tables for TABLE_PER_CLASS inheritance but the prod. oracle user does not have those create table priviledges and therefore that approach is not an option for our project.
Hibernate Version 5.2.8 is said to resolve that issue.
We updated our pom.xml accordingly to override default starter hibernate version setting.
Still we dont have any luck with the following property.
<property name="hibernate.hql.bulk_id_strategy"
value="org.hibernate.hql.spi.id.inline.InlineIdsInClauseBulkIdStrategy"
/>
APPLICATION PROPERTIES is also updated as follows
**
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:#192.168.1. :1521:
spring.datasource.username=
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.hql.bulk_id_strategy=org.hibernate.hql.spi.id.inline.InlineIdsInClauseBulkIdStrategy
**
Where is the proper location of this setting in a spring boot app?
The container is still generating temp tables in the test env. server startup.
kind regards
pom.xml is as follows
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>x.xx.ortakonline</groupId>
<artifactId>PolsanOrtakOnlineServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<jjwt.version>0.7.0</jjwt.version>
<hibernate.version>5.2.8.Final</hibernate.version>
</properties>
<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>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope> test </scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.mobile</groupId>
<artifactId>spring-mobile-device</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
</dependencies>
In addition all properties in spring.jpa.properties.* are passed through as normal JPA properties (with the prefix stripped) when the local EntityManagerFactory is created.
This comes from the JPA section in the Spring Boot reference guide and, in a nutshell, explains how to pass additional provider specific properties.
Adding the following to your application.properties should do the trick
spring.jpa.properties.hibernate.hql.bulk_id_strategy=org.hibernate.hql.spi.id.inline.InlineIdsInClauseBulkIdStrategy
As suggested by M.Deinum above, you should add the following to your application.properties file:
spring.jpa.properties.hibernate.hql.bulk_id_strategy=org.hibernate.hql.spi.id.inline.InlineIdsInClauseBulkIdStrategy
and also add the following to the properties section of your pom.xml to override the bundled hibernate-core library. This is to ensure that the InlineIdsInClauseBulkIdStrategy class is found, as the class is only available in Hibernate Core 5.3.1.Final and above:
<properties>
...
<hibernate.version>5.3.1.Final</hibernate.version>
</properties>

Resources