Forward to JSP within Spring Controller after form submission - spring

Using Spring #Controller, #RequestMapping and #ModelAttribute, I'd like to achieve a basic form submission flow in which the user is forwarded to a new JSP with attributes set. Spring provides different ways to achieve this, but I have received various errors.
Example 1
Based on tutorial: https://www.baeldung.com/spring-mvc-form-tutorial
form.html
<form action="/submitForm" method="POST">
<input type="text"id="field1" name="field1">
<!-- other input fields -->
<button type="submit">Submit</button>
</form>
success.jsp
<p>Thanks for signing up ${userName}!!</p>
MyController.java
#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String post(#ModelAttribute SignupRequest request, ModelMap model){
// At this point, the SignupRequest is populated correctly
model.addAttribute("userName", request.getUserName());
return "success";
}
}
Results
Using return "success" - the result is HTTP 404 Not Found
Using return "success.jsp", the result is HTTP 405 Request method
'POST' not supported
Using return "redirect:/success.jsp", the client is redirected,
but attributes are not set, and ${userName} is visible.
Example 2
Based on the accepted answer here: Redirect after POST method in spring MVC
MyController.java
#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ModelAndView post(#ModelAttribute SignupRequest request){
// At this point, the SignupRequest is populated correctly
ModelAndView mAV = new ModelAndView("redirect:/success.jsp");
mAV.addObject("userName", request.getUserName());
return mAV;
}
}
Result
the client is redirected, but attributes are not set, and ${userName} is visible.
What is the correct way to do this?
Thanks!
EDIT
Additional details
Using SpringBoot with embedded Tomcat. JSP file located in src>main>resources>public. The raw JSP is being served. I believe the project is not treating JSP as it should. Adding POM deps.
<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>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>

#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public RedirectView post(#ModelAttribute SignupRequest request, RedirectAttributes ra){
// At this point, the SignupRequest is populated correctly
RedirectView rw = new RedirectView();
rw.setUrl("success.jsp");
ra.addFlashAttribute("userName", request.getUserName());
return rw;
}
}

Related

Autowire JPA Repository with Hazelcast Map Store

I am using Spring-Boot, Spring-Data/JPA with Hazelcast client/server topology. I've been trying to use a MapStore as a Write-Behind buffer for my database through HazelcastRepository. My goal is to use a JpaRepository inside my MapStore to store sessions.
My current problem is that repository is not getting #Autowired, it always returns null.
Found this post about a similar situation, but it's not working because hazelcastClientInstance.getConfig().getManagedContext() is returning null.
Hazelcast configuration:
#Configuration
#EnableHazelcastRepositories(basePackages = {"com.xpto.database"})
#EnableJpaRepositories(basePackages = {"com.xpto.database"})
#ComponentScan(basePackages = {"com.xpto"})
public class HazelcastConfiguration {
#Bean
public SpringManagedContext managedContext() {
return new SpringManagedContext();
}
#Bean
HazelcastInstance hazelcastClientInstance(){
// Real all configuration from hazelcast-client file
ClientConfig clientConfig = null;
try {
clientConfig = new XmlClientConfigBuilder("hazelcast-client-config.xml").build().
setManagedContext(managedContext());
} catch (IOException e) {
e.printStackTrace();
}
return HazelcastClient.newHazelcastClient(clientConfig);
}
}
MapStore:
#SpringAware
public class SessionMapStore implements MapStore<String, Session>, MapLoaderLifecycleSupport {
private static final Logger LOGGER = LoggerFactory.getLogger(SessionMapStore.class);
#Autowired
private SessionsHCRepository sessionsHCRepository;
#Override
public void init(HazelcastInstance hazelcastClientInstance, Properties properties, String mapName) {
hazelcastClientInstance.getConfig().getManagedContext().initialize(this);
}
#Override
public void destroy() {
}
Repository:
#Repository
public interface SessionsHCRepository extends HazelcastRepository<SessionDB, String> {
}
pom file:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>javax.xml.rpc</groupId>
<artifactId>javax.xml.rpc-api</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-all</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>spring-data-hazelcast</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>

method level custom annotation doesn't work spring boot

I am trying to define custom annotation(LogMe) that should run before and after methods that are decorated with the annotation.
The annotation works fine for the spring identified methods - the ones defined with #GetMapping etc. however, the annotation on my custom written methods doesn't invoke AOP.
I have defined annotation as follows:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface LogMe {
My Aspect is like this:
#Configuration
#EnableAspectJAutoProxy
#Aspect
public class LogMeAspect {
#Pointcut("#annotation(com.api.logging.aspect.LogMe)")
public void loggableMethods() {}
#Around("loggableMethods()")
public Object serviceResponseTimeAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(">>>>>>>>>>>REACHING TO PJP:"+joinPoint.getSignature().getName());
Object obj = joinPoint.proceed();
return obj;
}
}
spring.factories defined as follows (I am trying to access this aspect from dependency).
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.api.logging.aspect.LoggingAspect,\
com.api.logging.aspect.LogMeAspect
usage of the annotation:
public class Utils {
#LogMe
public String testing(int i, int j, String str) {
System.out.println("in testing");
testing2();
return i+j+str;
}
#LogMe
public void testing2() {
System.out.println("in testing 2");
}
I have the following dependencies for my aspect module.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.4</version>
</dependency>
I have following dependencies for the module from where I am calling the aspect. of course, one of it is the aspect dependency - spring-boot-api-logging
<!-- core -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- matrix -->
<!-- kafka -->
<!-- tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- database -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- logging-->
<dependency>
<groupId>org.api.commons.logging</groupId>
<artifactId>spring-boot-api-logging</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

Spring Boot Google App Engine security annotation?

I'm currently working on a Spring Boot project with Google App Engine & I'm trying to check if my user is logged in on my controller actions thanks to annotations, like #PreAuthorize(isAuthenticated()). This annotation would return a HTTP 403 error if false.
Currently, my users are logged in with the Google App Engine basic UserService & I already tried to use this annotation without success (it does nothing).
Here is my pom file :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.1.3.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud</artifactId>
<version>0.47.0-alpha</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1-2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>materializecss</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.71</version>
</dependency>
I'm trying to make my code more readable currently I'm doing this on my controller :
private UserService userService = UserServiceFactory.getUserService();
#GetMapping("/pizza/create")
public String createPizza(Model model) {
if (!userService.isUserLoggedIn()) { // used in every actions that need an authentication check
return "error";
}
model.addAttribute("pizza", new Pizza());
return "create";
}
But I'd like to have this :
#PreAuthorize(isAuthenticated())
#GetMapping("/pizza/create")
public String createPizza(Model model) {
model.addAttribute("pizza", new Pizza());
return "create";
}

Configure LocaldateTime in Spring Rest API

I use Java 10 with latest Spring spring-boot-starter-parent 2.1.0.RELEASE
POM configuration:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.9.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.7</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.15</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-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</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-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
Rest Endpoint:
#GetMapping("{id}")
public ResponseEntity<?> get(#PathVariable String id) {
return transactionRepository
.findById(Integer.parseInt(id))
.map(mapper::toDTO)
.map(ResponseEntity::ok)
.orElseGet(() -> notFound().build());
}
DTO:
public class PaymentTransactionsDTO {
private Integer id;
private String status;
private LocalDateTime created_at;
private String merchant;
.... getters and setters
}
But when I try to return JSON data for LocalDateTime created_at I get empty result. I suppose that LocalDateTime is not properly converted into JSON value.
Can you advice how I can fix this issue?
JSON serialization is driven by Jackson's ObjectMapper, which I recommend configuring explicitely. For proper serialization of the Java 8 date and time objects, make sure to
register the JavaTimeModule
disable writing dates as timestamps
setting the date format (use StdDateFormat)
Description of StdDateFormat:
Default DateFormat implementation used by standard Date
serializers and deserializers. For serialization defaults to using an
ISO-8601 compliant format (format String "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
and for deserialization, both ISO-8601 and RFC-1123.
Recommended configuration:
#Configuration
public class JacksonConfig {
#Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.setAnnotationIntrospector(new JacksonAnnotationIntrospector())
.registerModule(new JavaTimeModule())
.setDateFormat(new StdDateFormat())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
}
Examples of serialized date and time objects:
LocalDate: 2018-11-21
LocalTime: 11:13:13.274
LocalDateTime: 2018-11-21T11:13:13.274
ZonedDateTime: 2018-11-21T11:13:13.274+01:00
Edit: standalone dependencies (already included transitively in spring-boot-starter-web):
com.fasterxml.jackson.core:jackson-annotations
com.fasterxml.jackson.core:jackson-databind
com.fasterxml.jackson.datatype:jackson-datatype-jsr310
Try using #JsonFormat on your created_at field.
#JsonFormat(pattern="yyyy-MM-dd")
#DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
private LocalDateTime created_at;
You need to add converter and register in spring eg.
baeldung.com/spring-mvc-custom-data-binder
You can type your PaymentTransactionsDTO "created_at" attribute as a String and use a converter to convert the String to LocalDate (type of the attribute created_at of your entity "PaymentTransactions")
#Component
public class PaymentTransactionsConverter implements Converter<PaymentTransactionsDTO, PaymentTransactions> {
#Override
public PaymentTransactions convert(PaymentTransactionsDTO paymentTransactionsDTO) {
PaymentTransactions paymentTransactions = new PaymentTransactions();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
...
paymentTransactions.setCreated_at(LocalDate.parse(paymentTransactionsDTO.getCreated_at(), formatter));
return paymentTransactions;
}
}
My dates defined as LocalDateTime were been serializaded as an array like this:
"timestamp": [
2023,
2,
15,
10,
30,
45,
732425200
],
So following the Peter Walser answer and using some code of that topic, here is what I did in my WebConfig.java:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
// other configs
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
WebMvcConfigurer.super.extendMessageConverters(converters);
converters.add(new MappingJackson2HttpMessageConverter(
new Jackson2ObjectMapperBuilder()
.dateFormat(new StdDateFormat())
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build()));
}
}
Now everything is good again:
"timestamp": "2023-02-15T10:32:06.5170689",
Try play around with some Jackson builder properties, hope it's been helpful.

Spring Boot attributes of the Model are not loaded on JSP page

I'm desperate, i'm following all the tutorials and the documentations, and i succesfully create a little hello controller with spring boot, but when i'm try to use spring boot on my project, all the attributes of the spring Model/Modelview are not loaded and i don't know why.
Here my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.github.p4535992</groupId>
<artifactId>springMVC12</artifactId>
<version>1.6.10</version>
<packaging>war</packaging>
<name>springMVC12</name>
<description>Demo project for Spring Boot using JSPs</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<!-- Generic properties -->
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<java.version>1.8</java.version>
<!-- Version of the Maven properties -->
<maven-eclipse-plugin.version>2.9</maven-eclipse-plugin.version>
<maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version>
<maven-source-plugin.version>2.3</maven-source-plugin.version>
<maven-javadoc-plugin.version>2.3</maven-javadoc-plugin.version>
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<maven-exec-plugin.version>1.1.1</maven-exec-plugin.version>
<maven-tomcat7-plugin.version>2.2</maven-tomcat7-plugin.version>
<maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
<mysql.version>5.1.6</mysql.version>
<javax.servlet.jstl.version>1.2</javax.servlet.jstl.version>
<!-- Json-->
<json-path.version>2.0.0</json-path.version>
<com.fasterxml.jackson.core.version>2.5.3</com.fasterxml.jackson.core.version>
<!-- Logging -->
<spring-boot-starter-logging.version>1.2.4.RELEASE</spring-boot-starter-logging.version>
<!-- Test -->
<junit.version>4.12</junit.version>
<com.github.dandelion.version>0.10.1</com.github.dandelion.version>
<!-- Apache and Commons -->
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.4</commons-io.version>
<commons-codec.version>1.10</commons-codec.version>
<!-- UTILITY Github -->
<com.github.p4535992.utility.version>1.6.10</com.github.p4535992.utility.version>
<!--<com.github.p4535992.gate-basic.version>1.6.5</com.github.p4535992.gate-basic.version>-->
<com.github.p4535992.ExtractInfo.version>1.6.10</com.github.p4535992.ExtractInfo.version>
<start-class>com.github.p4535992.mvc.JspDemoApplication</start-class>
<!-- <tomcat.version>7.0.52</tomcat.version>-->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.p4535992</groupId>
<artifactId>extractInfo</artifactId>
<version>${com.github.p4535992.ExtractInfo.version}</version>
<exclusions>
<exclusion>
<groupId>com.github.p4535992</groupId>
<artifactId>utility</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.p4535992</groupId>
<artifactId>utility</artifactId>
<version>${com.github.p4535992.utility.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- Other Spring boot dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<!-- <scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<!-- <scope>provided</scope>-->
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>-->
<!-- Github dependency -->
<dependency>
<groupId>com.github.p4535992</groupId>
<artifactId>extractInfo</artifactId>
</dependency>
<dependency>
<groupId>com.github.p4535992</groupId>
<artifactId>utility</artifactId>
</dependency>
<!-- MySQLDatabase -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- ===================== -->
<!-- Needed for JSON View -->
<!-- ===================== -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${com.fasterxml.jackson.core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${com.fasterxml.jackson.core.version}</version>
</dependency>
<!-- Need for get json response with controller -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${com.fasterxml.jackson.core.version}</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>${json-path.version}</version>
<scope>test</scope>
</dependency>
<!-- Dandelion -->
<dependency>
<groupId>com.github.dandelion</groupId>
<artifactId>datatables-jsp</artifactId>
<version>${com.github.dandelion.version}</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Apache and Commons -->
<!-- NOTE: commons-dbcp replace from tomcat-jdbc -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<!-- Needed for PDF View -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>4.2.1</version>
</dependency>
<!-- Needed for XLS View -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-beta2</version>
</dependency>
<!-- Needed for RSS View-->
<dependency>
<groupId>com.rometools</groupId>
<artifactId>rome</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- ****************************************-->
<!-- Copy dependency jar to a m2 folder -->
<!-- ****************************************-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${user.dir}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here my MapController.java:
#Controller
public class MapController {
private static final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(MapController.class);
#Autowired
private MapService mapService;
#Autowired
private FileService fileService;
private Marker marker;
private List<Marker> arrayMarker = new ArrayList<>();
private String arrayMarker2 ="";
//List<Marker> supportArray = new ArrayList<>();
private Integer indiceMarker = 0;
/*#RequestMapping(value="/map",method= RequestMethod.GET)
public String loadMap1(Model model){
String html = mapService.getResponseHTMLString();
return "riconciliazione2/mappa/map";
}
#RequestMapping(value="/map",method = RequestMethod.POST)
public String result(#RequestParam(required=false, value="urlParam")String url,Model model){
System.out.println("url: " + url);
return "home";
}*/
#RequestMapping(value="/map",method= RequestMethod.GET)
public String loadMap2(Model model){
//String html = mapService.getResponseHTMLString();
//Site siteForm = new Site();
//model.addAttribute("siteForm",siteForm);
if(!arrayMarker.isEmpty()) model.addAttribute("arrayMarker",arrayMarker);
else model.addAttribute("arrayMarker",null);
arrayMarker2 = JsonUtilities.writeListToJsonArray(arrayMarker);
if(arrayMarker2 != null) model.addAttribute("arrayMarker2",arrayMarker2);
else model.addAttribute("arrayMarker2","");
if(marker!=null)model.addAttribute("marker",marker);
else model.addAttribute("marker",null);
model.addAttribute("indiceMarker",indiceMarker);
model.addAttribute("urlParam",null);
String html = mapService.getResponseHTMLString();
model.addAttribute("HTML",html);
return "riconciliazione2/mappa/leafletMap";
}
/*#RequestMapping("*")
public String hello(HttpServletRequest request,Model model) {
System.out.println(request.getServletPath());
String MAIN = mapService.homeMain();
model.addAttribute("MAIN",MAIN);
return "main";
}*/
#RequestMapping("/")
public String homeMain(Model model){
return "main";
}
#RequestMapping(value="/main",method= RequestMethod.GET)
public String homeMain2(Model model){
//String MAIN = mapService.homeMain();
//model.addAttribute("MAIN",MAIN);
return "main";
}
//---------------------------------------------------------
// NEW GET METHOD
//---------------------------------------------------------
#RequestMapping(value="/map13",method= RequestMethod.GET)
public String loadMap13(){
Model model = new ExtendedModelMap();
//String html = mapService.getResponseHTMLString();
//Site siteForm = new Site();
//model.addAttribute("siteForm",siteForm);
if(!arrayMarker.isEmpty()) model.addAttribute("arrayMarker",arrayMarker);
else model.addAttribute("arrayMarker",null);
arrayMarker2 = JsonUtilities.writeListToJsonArray(arrayMarker);
if(arrayMarker2 != null) model.addAttribute("arrayMarker2",arrayMarker2);
else model.addAttribute("arrayMarker2",null);
if(marker!=null)model.addAttribute("marker",marker);
else model.addAttribute("marker",null);
model.addAttribute("indiceMarker",indiceMarker);
model.addAttribute("urlParam",null);
//String html = mapService.getResponseHTMLString();
//model.addAttribute("HTML",html);
//model.addAttribute("supportArray",supportArray);
return "riconciliazione2/mappa/leafletMap5";
}
//---------------------------------------------------------
// NEW POST METHOD
//---------------------------------------------------------
#RequestMapping(value="/map3",method = RequestMethod.POST)
public String result4(#RequestParam(required=false, value="urlParam")String url,
#RequestParam(required=false,value="arrayParam")List<String> arrayParam
//#ModelAttribute(value="arrayParam") MarkerList arrayParam
//#ModelAttribute(value="markerParam")Marker markerFromJS
){
if(arrayParam!= null && !arrayParam.isEmpty()){
for(String smarker : arrayParam){
if(StringUtilities.isNullOrEmpty(smarker))continue;
marker = new Marker();
try {
marker = JsonUtilities.fromJson(smarker,Marker.class);
} catch (IOException ioe) {
ioe.printStackTrace();
}
arrayMarker.add(marker);
indiceMarker++;
}
}
if(!StringUtilities.isNullOrEmpty(url)) {
String[] splitter;
if (url.contains(",")) {
splitter = url.split(",");
url = splitter[0];
}
System.out.println("url: " + url);
marker = new Marker();
marker = mapService.createMarkerFromGeoDocument(url);
// = new Marker("City",url,"43.3555664", "11.0290384");
//model.addAttribute("marker",marker); //no need is get from the HTTTP GET COMMAND
arrayMarker.add(marker);
indiceMarker++;
}
return "redirect:/map13";
}
Here the link to my JSP page: JSPPage
I don't know why but the attribute arrayMarker2 is always empty, and that give me nuts.
You can find the full code of the project to this link springMVC12.
Ty in advance for any help.
Ok, i solved by myself but i not sure how.
I just replace all the Model of springframework with the ModelAndView Object.

Resources