BAEL-5575 (#14016)
* BAEL-5575 First commit of the example for the article: https://drafts.baeldung.com/wp-admin/post.php?post=153774&action=edit * BAEL-5575 Adjusted pom.xml * BAEL-5575 Formatted source code * BAEL-5575 Removed unused import * BAEL-5575 Renamed UT to follow: https://docs.google.com/document/d/1iIeSPuYFG-jEtB8UbcxQnn2AI3OR2LWlnisNo2NUCL8/edit * BAEL-5575 Modified pom.xml to define versions in properties as stated in: https://docs.google.com/document/d/1iIeSPuYFG-jEtB8UbcxQnn2AI3OR2LWlnisNo2NUCL8/edit * BAEL-5575 Changes checking the commands: * mvn clean install * mvn clean install -Dgib.enabled=false * BAEL-5575 Set GB as the base language
This commit is contained in:
parent
50faedd2bc
commit
9fb2b4d919
|
@ -0,0 +1,4 @@
|
|||
--add-opens=java.base/java.util=ALL-UNNAMED
|
||||
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
|
||||
--add-opens=java.base/java.text=ALL-UNNAMED
|
||||
--add-opens=java.desktop/java.awt.font=ALL-UNNAMED
|
|
@ -0,0 +1,95 @@
|
|||
<?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/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung.spring-thymeleaf-attributes.module</groupId>
|
||||
<artifactId>accessing-session-attributes</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring-thymeleaf-attributes</groupId>
|
||||
<artifactId>spring-thymeleaf-attributes-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring6</artifactId>
|
||||
<version>${thymeleaf.spring6.version}</version>
|
||||
</dependency>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.engine.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.engine.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<jvmArguments>
|
||||
-Dfile.encoding="UTF-8" -Xdebug
|
||||
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
|
||||
</jvmArguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<start-class>com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer</start-class>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<file.encoding>UTF-8</file.encoding>
|
||||
<downloadSources>true</downloadSources>
|
||||
<downloadJavadocs>true</downloadJavadocs>
|
||||
<junit.jupiter.engine.version>5.9.3</junit.jupiter.engine.version>
|
||||
<mockito.version>5.3.1</mockito.version>
|
||||
<thymeleaf.spring6.version>3.1.1.RELEASE</thymeleaf.spring6.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.accesing_session_attributes;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringWebApplicationInitializer {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public SpringWebApplicationInitializer() {
|
||||
super();
|
||||
String encoding = System.getProperty("file.encoding");
|
||||
log.info(encoding);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringWebApplicationInitializer.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.accesing_session_attributes.business;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity;
|
||||
|
||||
@Service
|
||||
public interface AgeAnalysisService {
|
||||
ResponseEntity<NameAgeEntity> getAgeAnalysisForName(String nameToAnalyze);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.accesing_session_attributes.business;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity;
|
||||
|
||||
@Service
|
||||
public interface CountryAnalysisService {
|
||||
ResponseEntity<NameCountriesEntity> getCountryAnalysisForName(String nameToAnalyze);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.accesing_session_attributes.business;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity;
|
||||
|
||||
@Service
|
||||
public interface GenderAnalysisService {
|
||||
ResponseEntity<NameGenderEntity> getGenderAnalysisForName(String nameToAnalyze);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.accesing_session_attributes.business;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity;
|
||||
|
||||
@Service
|
||||
public interface NameAnalysisService {
|
||||
public NameRequest getLastNameRequest();
|
||||
|
||||
public CompletableFuture<NameAnalysisEntity> searchForName(NameRequest nameRequest);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.accesing_session_attributes.business.beans;
|
||||
|
||||
public class NameRequest {
|
||||
private String name;
|
||||
|
||||
public NameRequest() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameRequest other = (NameRequest) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameRequestEntity [name=" + name + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities;
|
||||
|
||||
/**
|
||||
* https://api.agify.io/?name=michael
|
||||
*/
|
||||
public class NameAgeEntity {
|
||||
private Integer age;
|
||||
private Long count;
|
||||
private String name;
|
||||
|
||||
public NameAgeEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Integer getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(Integer age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((age == null) ? 0 : age.hashCode());
|
||||
result = prime * result + ((count == null) ? 0 : count.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameAgeEntity other = (NameAgeEntity) obj;
|
||||
if (age == null) {
|
||||
if (other.age != null)
|
||||
return false;
|
||||
} else if (!age.equals(other.age))
|
||||
return false;
|
||||
if (count == null) {
|
||||
if (other.count != null)
|
||||
return false;
|
||||
} else if (!count.equals(other.count))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameAgeEntity [age=" + age + ", count=" + count + ", name=" + name + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities;
|
||||
|
||||
public class NameAnalysisEntity {
|
||||
private String name;
|
||||
private NameAgeEntity age;
|
||||
private NameCountriesEntity countries;
|
||||
private NameGenderEntity gender;
|
||||
|
||||
public NameAnalysisEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public NameAgeEntity getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(NameAgeEntity age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public NameCountriesEntity getCountries() {
|
||||
return countries;
|
||||
}
|
||||
|
||||
public void setCountries(NameCountriesEntity countries) {
|
||||
this.countries = countries;
|
||||
}
|
||||
|
||||
public NameGenderEntity getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(NameGenderEntity gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((age == null) ? 0 : age.hashCode());
|
||||
result = prime * result + ((countries == null) ? 0 : countries.hashCode());
|
||||
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameAnalysisEntity other = (NameAnalysisEntity) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (age == null) {
|
||||
if (other.age != null)
|
||||
return false;
|
||||
} else if (!age.equals(other.age))
|
||||
return false;
|
||||
if (countries == null) {
|
||||
if (other.countries != null)
|
||||
return false;
|
||||
} else if (!countries.equals(other.countries))
|
||||
return false;
|
||||
if (gender == null) {
|
||||
if (other.gender != null)
|
||||
return false;
|
||||
} else if (!gender.equals(other.gender))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameAnalysisEntity [name=" + name + ", age=" + age + ", countries=" + countries + ", gender=" + gender + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* https://api.nationalize.io/?name=michael
|
||||
*/
|
||||
public class NameCountriesEntity {
|
||||
private String name;
|
||||
private List<NameCountryEntity> country;
|
||||
|
||||
public NameCountriesEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<NameCountryEntity> getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(List<NameCountryEntity> country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((country == null) ? 0 : country.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameCountriesEntity other = (NameCountriesEntity) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (country == null) {
|
||||
if (other.country != null)
|
||||
return false;
|
||||
} else if (!country.equals(other.country))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameCountriesModel [name=" + name + ", country=" + country + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities;
|
||||
|
||||
/**
|
||||
* NameCountryModel
|
||||
*
|
||||
* https://www.countryflagicons.com/
|
||||
* <img src="https://www.countryflagicons.com/STYLE/size/COUNTRYCODE.png">
|
||||
* STYLE: FLAT, SHINY
|
||||
* size: 16, 24, 32, 48, 64
|
||||
* COUNTRYCODE: country_id
|
||||
*/
|
||||
public class NameCountryEntity {
|
||||
private String country_id;
|
||||
private Float probability;
|
||||
|
||||
public NameCountryEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getCountry_id() {
|
||||
return country_id;
|
||||
}
|
||||
|
||||
public void setCountry_id(String country_id) {
|
||||
this.country_id = country_id;
|
||||
}
|
||||
|
||||
public Float getProbability() {
|
||||
return probability;
|
||||
}
|
||||
|
||||
public void setProbability(Float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((country_id == null) ? 0 : country_id.hashCode());
|
||||
result = prime * result + ((probability == null) ? 0 : probability.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameCountryEntity other = (NameCountryEntity) obj;
|
||||
if (country_id == null) {
|
||||
if (other.country_id != null)
|
||||
return false;
|
||||
} else if (!country_id.equals(other.country_id))
|
||||
return false;
|
||||
if (probability == null) {
|
||||
if (other.probability != null)
|
||||
return false;
|
||||
} else if (!probability.equals(other.probability))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameCountryModel [country_id=" + country_id + ", probability=" + probability + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities;
|
||||
|
||||
/**
|
||||
* NameGenderModel
|
||||
* https://api.genderize.io/?name=victor
|
||||
*/
|
||||
public class NameGenderEntity {
|
||||
private Long count;
|
||||
private String gender;
|
||||
private String name;
|
||||
private Float probability;
|
||||
|
||||
public NameGenderEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Float getProbability() {
|
||||
return probability;
|
||||
}
|
||||
|
||||
public void setProbability(Float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((count == null) ? 0 : count.hashCode());
|
||||
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((probability == null) ? 0 : probability.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NameGenderEntity other = (NameGenderEntity) obj;
|
||||
if (count == null) {
|
||||
if (other.count != null)
|
||||
return false;
|
||||
} else if (!count.equals(other.count))
|
||||
return false;
|
||||
if (gender == null) {
|
||||
if (other.gender != null)
|
||||
return false;
|
||||
} else if (!gender.equals(other.gender))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (probability == null) {
|
||||
if (other.probability != null)
|
||||
return false;
|
||||
} else if (!probability.equals(other.probability))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NameGenderModel [count=" + count + ", gender=" + gender + ", name=" + name + ", probability=" + probability + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.accesing_session_attributes.business.entities.factories;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity;
|
||||
|
||||
@Service
|
||||
public class NameAnalysisEntityFactory {
|
||||
|
||||
public NameAnalysisEntity getInstance(String nameRequest, NameGenderEntity gender, NameAgeEntity age, NameCountriesEntity countries) {
|
||||
NameAnalysisEntity nameAnalysis = new NameAnalysisEntity();
|
||||
nameAnalysis.setName(nameRequest);
|
||||
nameAnalysis.setGender(gender);
|
||||
nameAnalysis.setAge(age);
|
||||
nameAnalysis.setCountries(countries);
|
||||
return nameAnalysis;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.accesing_session_attributes.business.impl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.AgeAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity;
|
||||
|
||||
@Component
|
||||
public class AgeAnalysisServiceImpl implements AgeAnalysisService {
|
||||
@Value("${name-analysis-controller.name-age-api-url:https://api.agify.io/?name={0}}")
|
||||
private String nameAgeApiUrl;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<NameAgeEntity> getAgeAnalysisForName(String nameToAnalyze) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
return restTemplate.getForEntity(URI.create(MessageFormat.format(nameAgeApiUrl, nameToAnalyze)), NameAgeEntity.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.accesing_session_attributes.business.impl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.CountryAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity;
|
||||
|
||||
@Component
|
||||
public class CountryAnalysisServiceImpl implements CountryAnalysisService {
|
||||
@Value("${name-analysis-controller.name-countries-api-url:https://api.nationalize.io/?name={0}}")
|
||||
private String nameCountriesApiUrl;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<NameCountriesEntity> getCountryAnalysisForName(String nameToAnalyze) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
return restTemplate.getForEntity(URI.create(MessageFormat.format(nameCountriesApiUrl, nameToAnalyze)), NameCountriesEntity.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.accesing_session_attributes.business.impl;
|
||||
|
||||
import java.net.URI;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.GenderAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity;
|
||||
|
||||
@Component
|
||||
public class GenderAnalysisServiceImpl implements GenderAnalysisService {
|
||||
@Value("${name-analysis-controller.name-gender-api-url:https://api.genderize.io/?name={0}}")
|
||||
private String nameGenderApiUrl;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<NameGenderEntity> getGenderAnalysisForName(String nameToAnalyze) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
return restTemplate.getForEntity(URI.create(MessageFormat.format(nameGenderApiUrl, nameToAnalyze)), NameGenderEntity.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.accesing_session_attributes.business.impl;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.AgeAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.CountryAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.GenderAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.NameAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.factories.NameAnalysisEntityFactory;
|
||||
|
||||
@Component
|
||||
public class NameAnalysisServiceImpl implements NameAnalysisService {
|
||||
|
||||
private NameRequest lastNameRequest;
|
||||
private AgeAnalysisService ageAnalysisService;
|
||||
private CountryAnalysisService countryAnalysisService;
|
||||
private GenderAnalysisService genderAnalysisService;
|
||||
private NameAnalysisEntityFactory nameAnalysisEntityFactory;
|
||||
|
||||
@Autowired
|
||||
public NameAnalysisServiceImpl(AgeAnalysisService ageAnalysisService, CountryAnalysisService countryAnalysisService, GenderAnalysisService genderAnalysisService, NameAnalysisEntityFactory nameAnalysisEntityFactory) {
|
||||
super();
|
||||
this.ageAnalysisService = ageAnalysisService;
|
||||
this.countryAnalysisService = countryAnalysisService;
|
||||
this.genderAnalysisService = genderAnalysisService;
|
||||
this.nameAnalysisEntityFactory = nameAnalysisEntityFactory;
|
||||
|
||||
lastNameRequest = new NameRequest();
|
||||
lastNameRequest.setName("Rigoberto");
|
||||
}
|
||||
|
||||
public NameRequest getLastNameRequest() {
|
||||
return lastNameRequest;
|
||||
}
|
||||
|
||||
public CompletableFuture<NameAnalysisEntity> searchForName(NameRequest nameRequest) {
|
||||
this.lastNameRequest.setName(nameRequest.getName());
|
||||
return analyzeName();
|
||||
}
|
||||
|
||||
@Async
|
||||
private CompletableFuture<NameAnalysisEntity> analyzeName() {
|
||||
try {
|
||||
String nameToAnalyze = URLEncoder.encode(lastNameRequest.getName(), "UTF-8");
|
||||
|
||||
ResponseEntity<NameAgeEntity> ageRequestResponse = ageAnalysisService.getAgeAnalysisForName(nameToAnalyze);
|
||||
ResponseEntity<NameCountriesEntity> countriesRequestResponse = countryAnalysisService.getCountryAnalysisForName(nameToAnalyze);
|
||||
ResponseEntity<NameGenderEntity> genderRequestResponse = genderAnalysisService.getGenderAnalysisForName(nameToAnalyze);
|
||||
|
||||
NameAnalysisEntity nameAnalysis = nameAnalysisEntityFactory.getInstance(lastNameRequest.getName(), genderRequestResponse.getBody(), ageRequestResponse.getBody(), countriesRequestResponse.getBody());
|
||||
return CompletableFuture.completedFuture(nameAnalysis);
|
||||
|
||||
} catch (Exception e) {
|
||||
return CompletableFuture.failedFuture(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.accesing_session_attributes.web;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.web.servlet.JakartaServletWebApplication;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class SpringWebConfig implements WebMvcConfigurer, ApplicationContextAware {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
public SpringWebConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.webApplicationContext = (WebApplicationContext) applicationContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispatcher configuration for serving static resources
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||
WebMvcConfigurer.super.addResourceHandlers(registry);
|
||||
registry.addResourceHandler("/images/**")
|
||||
.addResourceLocations("/images/");
|
||||
registry.addResourceHandler("/css/**")
|
||||
.addResourceLocations("/css/");
|
||||
registry.addResourceHandler("/js/**")
|
||||
.addResourceLocations("/js/");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceBundleMessageSource messageSource() {
|
||||
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||
messageSource.addBasenames("name-analysis");
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringResourceTemplateResolver templateResolver() {
|
||||
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
|
||||
templateResolver.setApplicationContext(this.webApplicationContext);
|
||||
templateResolver.setPrefix("/WEB-INF/templates/");
|
||||
templateResolver.setSuffix(".html");
|
||||
|
||||
templateResolver.setTemplateMode(TemplateMode.HTML);
|
||||
templateResolver.setCacheable(true);
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringTemplateEngine templateEngine() {
|
||||
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
|
||||
templateEngine.setMessageSource(webApplicationContext);
|
||||
templateEngine.setTemplateResolver(templateResolver());
|
||||
return templateEngine;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ThymeleafViewResolver viewResolver() {
|
||||
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
|
||||
viewResolver.setTemplateEngine(templateEngine());
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JakartaServletWebApplication jakartaServletWebApplication() {
|
||||
return JakartaServletWebApplication.buildApplication(webApplicationContext.getServletContext());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.accesing_session_attributes.web.beans;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
|
||||
public class SessionNameRequest {
|
||||
private Date requestDate;
|
||||
private NameRequest nameRequest;
|
||||
|
||||
public SessionNameRequest() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Date getRequestDate() {
|
||||
return requestDate;
|
||||
}
|
||||
|
||||
public void setRequestDate(Date requestDate) {
|
||||
this.requestDate = requestDate;
|
||||
}
|
||||
|
||||
public NameRequest getNameRequest() {
|
||||
return nameRequest;
|
||||
}
|
||||
|
||||
public void setNameRequest(NameRequest nameRequest) {
|
||||
this.nameRequest = nameRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((requestDate == null) ? 0 : requestDate.hashCode());
|
||||
result = prime * result + ((nameRequest == null) ? 0 : nameRequest.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SessionNameRequest other = (SessionNameRequest) obj;
|
||||
if (requestDate == null) {
|
||||
if (other.requestDate != null)
|
||||
return false;
|
||||
} else if (!requestDate.equals(other.requestDate))
|
||||
return false;
|
||||
if (nameRequest == null) {
|
||||
if (other.nameRequest != null)
|
||||
return false;
|
||||
} else if (!nameRequest.equals(other.nameRequest))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SessionNameRequest [requestDate=" + requestDate + ", nameRequest=" + nameRequest + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package com.baeldung.accesing_session_attributes.web.controllers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.thymeleaf.web.IWebSession;
|
||||
import org.thymeleaf.web.servlet.IServletWebExchange;
|
||||
import org.thymeleaf.web.servlet.JakartaServletWebApplication;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.NameAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity;
|
||||
import com.baeldung.accesing_session_attributes.web.beans.SessionNameRequest;
|
||||
import com.baeldung.accesing_session_attributes.web.factories.SessionNameRequestFactory;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
@Controller
|
||||
public class NameAnalysisController {
|
||||
|
||||
private NameAnalysisService nameAnalysisService;
|
||||
private HttpServletRequest request;
|
||||
private SessionNameRequestFactory sessionNameRequestFactory;
|
||||
private HttpServletResponse response;
|
||||
private JakartaServletWebApplication jakartaServletWebApplication;
|
||||
|
||||
@Autowired
|
||||
public NameAnalysisController(JakartaServletWebApplication jakartaServletWebApplication, HttpServletRequest request, HttpServletResponse response, NameAnalysisService nameAnalysisService, SessionNameRequestFactory sessionNameRequestFactory) {
|
||||
super();
|
||||
this.jakartaServletWebApplication = jakartaServletWebApplication;
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.nameAnalysisService = nameAnalysisService;
|
||||
this.sessionNameRequestFactory = sessionNameRequestFactory;
|
||||
}
|
||||
|
||||
@ModelAttribute("nameRequest")
|
||||
public NameRequest nameRequest() {
|
||||
return nameAnalysisService.getLastNameRequest();
|
||||
}
|
||||
|
||||
@RequestMapping({ "/", "/name-analysis" })
|
||||
public String showNameAnalysis() {
|
||||
return "name-analysis";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/name-analysis", params = { "search" })
|
||||
public String performNameAnalysis(final NameRequest nameRequest, final BindingResult bindingResult) {
|
||||
performNameRequest(nameRequest);
|
||||
return "name-analysis";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/name-analysis/clear")
|
||||
public String clearNameAnalysis() {
|
||||
clearAnalysis();
|
||||
return "redirect:/name-analysis";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/name-analysis/remove-history-request", params = { "id" })
|
||||
public String removeRequest() {
|
||||
try {
|
||||
final Integer rowId = Integer.valueOf(request.getParameter("id"));
|
||||
removeRequest(rowId);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "redirect:/name-analysis";
|
||||
}
|
||||
|
||||
private void removeRequest(Integer rowId) {
|
||||
IWebSession session = getIWebSession();
|
||||
Object requests = session.getAttributeValue("requests");
|
||||
if (rowId != null && requests != null && (requests instanceof List)) {
|
||||
((List<SessionNameRequest>) requests).remove(rowId.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void performNameRequest(final NameRequest nameRequest) {
|
||||
try {
|
||||
CompletableFuture<NameAnalysisEntity> nameAnalysis = this.nameAnalysisService.searchForName(nameRequest);
|
||||
NameAnalysisEntity nameAnalysisEntity = nameAnalysis.get(30, TimeUnit.SECONDS);
|
||||
sessionRegisterRequest(nameRequest);
|
||||
sessionRegisterAnalysis(nameAnalysisEntity);
|
||||
sessionClearAnalysisError();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
sessionSetAnalysisError(nameRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private void sessionClearAnalysisError() {
|
||||
IWebSession session = getIWebSession();
|
||||
session.setAttributeValue("analysisError", null);
|
||||
}
|
||||
|
||||
private void sessionSetAnalysisError(NameRequest nameRequest) {
|
||||
IWebSession session = getIWebSession();
|
||||
session.setAttributeValue("analysisError", nameRequest);
|
||||
}
|
||||
|
||||
private void clearAnalysis() {
|
||||
IWebSession session = getIWebSession();
|
||||
session.setAttributeValue("lastAnalysis", null);
|
||||
}
|
||||
|
||||
private void sessionRegisterAnalysis(NameAnalysisEntity analysis) {
|
||||
IWebSession session = getIWebSession();
|
||||
session.setAttributeValue("lastAnalysis", analysis);
|
||||
}
|
||||
|
||||
private void sessionRegisterRequest(NameRequest nameRequest) {
|
||||
IWebSession session = getIWebSession();
|
||||
session.setAttributeValue("lastRequest", nameRequest);
|
||||
|
||||
SessionNameRequest sessionNameRequest = sessionNameRequestFactory.getInstance(nameRequest);
|
||||
List<SessionNameRequest> requests = getRequestsFromSession(session);
|
||||
requests.add(0, sessionNameRequest);
|
||||
}
|
||||
|
||||
private List<SessionNameRequest> getRequestsFromSession(IWebSession session) {
|
||||
Object requests = session.getAttributeValue("requests");
|
||||
if (requests == null || !(requests instanceof List)) {
|
||||
List<SessionNameRequest> sessionNameRequests = new ArrayList<>();
|
||||
session.setAttributeValue("requests", sessionNameRequests);
|
||||
requests = sessionNameRequests;
|
||||
}
|
||||
return (List<SessionNameRequest>) requests;
|
||||
}
|
||||
|
||||
private IWebSession getIWebSession() {
|
||||
IServletWebExchange webExchange = this.jakartaServletWebApplication.buildExchange(request, response);
|
||||
return webExchange.getSession();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.accesing_session_attributes.web.factories;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
import com.baeldung.accesing_session_attributes.web.beans.SessionNameRequest;
|
||||
|
||||
@Service
|
||||
public class SessionNameRequestFactory {
|
||||
|
||||
public SessionNameRequest getInstance(NameRequest nameRequest) {
|
||||
|
||||
NameRequest cloned = new NameRequest();
|
||||
cloned.setName(nameRequest.getName());
|
||||
|
||||
SessionNameRequest sessionNameRequest = new SessionNameRequest();
|
||||
sessionNameRequest.setRequestDate(new Date());
|
||||
sessionNameRequest.setNameRequest(cloned);
|
||||
|
||||
return sessionNameRequest;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
spring.http.encoding.enabled=true
|
||||
spring.devtools.add-properties=false
|
||||
logging.level.web=DEBUG
|
|
@ -0,0 +1,20 @@
|
|||
history.header.actions=Actions
|
||||
history.header.date=Date
|
||||
history.header.name=Name
|
||||
history.no-data=Without data
|
||||
history.request.remove-row=Remove row
|
||||
history.title=Requests History
|
||||
name-analysis.form.button.analyze=Analyze
|
||||
name-analysis.form.name=Name
|
||||
name-analysis.title=Analyze name
|
||||
result.clear=Borrar
|
||||
result.column.age-count=Number of persons
|
||||
result.column.age=Age
|
||||
result.column.city=City
|
||||
result.column.gender=Gender
|
||||
result.column.name=Name
|
||||
result.error=Error during analysis
|
||||
result.header.value=Value
|
||||
result.no-request-performed=Without data
|
||||
result.title=Name analyzed
|
||||
web.title=Baeldung - Accessing Session Attributes in Thymeleaf
|
|
@ -0,0 +1,20 @@
|
|||
history.header.actions=Actions
|
||||
history.header.date=Date
|
||||
history.header.name=Name
|
||||
history.no-data=Without data
|
||||
history.request.remove-row=Remove row
|
||||
history.title=Requests History
|
||||
name-analysis.form.button.analyze=Analyze
|
||||
name-analysis.form.name=Name
|
||||
name-analysis.title=Analyze name
|
||||
result.clear=Borrar
|
||||
result.column.age-count=Number of persons
|
||||
result.column.age=Age
|
||||
result.column.city=City
|
||||
result.column.gender=Gender
|
||||
result.column.name=Name
|
||||
result.error=Error during analysis
|
||||
result.header.value=Value
|
||||
result.no-request-performed=Without data
|
||||
result.title=Name analyzed
|
||||
web.title=Baeldung - Accessing Session Attributes in Thymeleaf
|
|
@ -0,0 +1,20 @@
|
|||
history.header.actions=Acciones
|
||||
history.header.date=Fecha
|
||||
history.header.name=Nombre
|
||||
history.no-data=Sin datos
|
||||
history.request.remove-row=Eliminar fila
|
||||
history.title=Historial
|
||||
name-analysis.form.button.analyze=Analizar
|
||||
name-analysis.form.name=Nombre
|
||||
name-analysis.title=Analizar nombre
|
||||
result.clear=Borrar
|
||||
result.column.age-count=Ocurrencias
|
||||
result.column.age=Edad
|
||||
result.column.city=Ciudad
|
||||
result.column.gender=Género
|
||||
result.column.name=Nombre
|
||||
result.error=Se produjo un error
|
||||
result.header.value=Valor
|
||||
result.no-request-performed=Sin datos
|
||||
result.title=Nombre analizado
|
||||
web.title=Baeldung - Acceso a los atributos de la sesión con Thymeleaf
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<title data-th-text="#{web.title}">Baeldung - Accessing Session Attributes in Thymeleaf</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
</head>
|
||||
|
||||
<body class="full-container px-4">
|
||||
<div class="row py-5">
|
||||
<div class="col-5 px-4">
|
||||
<div class="border mx-auto">
|
||||
<h5 class="display-5 text-center mb-3" data-th-text="#{name-analysis.title}">Analizar nombre</h5>
|
||||
<div class="border-top py-4">
|
||||
<form class="px-4 mb-3" action="#" data-th-action="@{/name-analysis}" data-th-object="${nameRequest}"
|
||||
method="post">
|
||||
<div class="border rounded-3 px-4 py-4 bg-light">
|
||||
<div class="col-12 mb-3">
|
||||
<label for="name" class="form-label" data-th-text="#{name-analysis.form.name}">Nombre</label>
|
||||
<input id="name" type="text" class="form-control" data-th-field="*{name}" placeholder value required>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group me-2">
|
||||
<button class="btn btn-lg btn-primary" type="submit" name="search"
|
||||
data-th-text="#{name-analysis.form.button.analyze}">Analizar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-4" />
|
||||
|
||||
<div class="border mx-auto">
|
||||
<h5 class="display-5 text-center mb-3" data-th-text="#{result.title}">Nombre analizado</h5>
|
||||
<div class="border-top py-4">
|
||||
<h4 class="display-6 text-center" data-th-if="${#ctx.session.analysisError}!=null"
|
||||
data-th-text="#{result.error}">Error durante el análisis</h4>
|
||||
<h4 class="display-6 text-center"
|
||||
data-th-if="${#ctx.session.analysisError}==null and ${#ctx.session.lastAnalysis}==null"
|
||||
data-th-text="#{result.no-request-performed}">Sin búsquedas</h4>
|
||||
<div data-th-if="${#ctx.session.analysisError}==null and ${#ctx.session.lastAnalysis}!=null"
|
||||
data-th-object="${#ctx.session.lastAnalysis}">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="px-2" scope="col">#</th>
|
||||
<th class="px-2" scope="col" data-th-text="#{result.header.value}">Valor</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" data-th-text="#{result.column.name}">Nombre</th>
|
||||
<td><span data-th-text="*{name}">Nombre buscado</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" data-th-text="#{result.column.gender}">Género</th>
|
||||
<td><span data-th-text="*{gender.gender}">[Masculino|Femenino]</span> (<span
|
||||
data-th-text="*{gender.probability}">{%}</span>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" data-th-text="#{result.column.age}">Edad</th>
|
||||
<td><span data-th-text="*{age.age}">{Edad media del nombre}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row" data-th-text="#{result.column.age-count}">Número de personas<h>
|
||||
<td><span data-th-text="*{age.count}">{Número de personas}</span></td>
|
||||
</tr>
|
||||
<tr data-th-each="country : *{countries.country}">
|
||||
<th scope="row" data-th-text="#{result.column.city}">Ciudad</th>
|
||||
<td><span data-th-text="${country.country_id}">Country id</span> (<span
|
||||
data-th-text="${country.probability}">{%}</span>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="px-2">
|
||||
<a class="btn btn-lg btn-danger px-2" data-th-href="@{/name-analysis/clear}"
|
||||
data-th-text="#{result.clear}">Borrar</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-7">
|
||||
<div class="border mx-auto">
|
||||
<h5 class="display-5 text-center mb-3" data-th-text="#{history.title}">Historial</h5>
|
||||
<div class="border-top py-4">
|
||||
<h4 class="display-6 text-center"
|
||||
data-th-if="${#ctx.session.requests}==null or ${#ctx.session.requests.isEmpty()}"
|
||||
data-th-text="#{history.no-data}">Sin datos</h4>
|
||||
<table data-th-if="${#ctx.session.requests}!=null and ${not #ctx.session.requests.isEmpty()}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="px-2" data-th-text="#{history.header.date}">Fecha</th>
|
||||
<th class="px-2" data-th-text="#{history.header.name}">Nombre</th>
|
||||
<th class="px-2" data-th-text="#{history.header.actions}">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-th-each="request,rowStat : ${#ctx.session.requests}">
|
||||
<td class="px-2">[[${request.requestDate}]]</td>
|
||||
<td class="px-2">[[${request.nameRequest}]]</td>
|
||||
<td class="px-2">
|
||||
<a class="btn btn-danger px-2" name="remove-request"
|
||||
data-th-href="@{/name-analysis/remove-history-request(id=${rowStat.index})}"
|
||||
data-th-text="#{history.request.remove-row}">Remove row</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,107 @@
|
|||
package com.baeldung.accesing_session_attributes.business.impl;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import com.baeldung.accesing_session_attributes.business.AgeAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.CountryAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.GenderAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.NameAnalysisService;
|
||||
import com.baeldung.accesing_session_attributes.business.beans.NameRequest;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAgeEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameAnalysisEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameCountriesEntity;
|
||||
import com.baeldung.accesing_session_attributes.business.entities.NameGenderEntity;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest
|
||||
@ActiveProfiles({ "test" })
|
||||
public class NameAnalysisServiceImplUnitTest {
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper om;
|
||||
@MockBean
|
||||
private AgeAnalysisService ageAnalysisService;
|
||||
@MockBean
|
||||
private CountryAnalysisService countryAnalysisService;
|
||||
@MockBean
|
||||
private GenderAnalysisService genderAnalysisService;
|
||||
@Autowired
|
||||
private NameAnalysisService toTest;
|
||||
|
||||
@Test
|
||||
void givenRigoberto_whenCallCompletesOk_thenNameAnalysisEntityReceived()
|
||||
throws JsonMappingException, JsonProcessingException {
|
||||
String nameToAnalyze = "Rigoberto";
|
||||
NameAgeEntity rigobertoAgeAnalysis = om.readValue("{\"age\":68,\"count\":683,\"name\":\"Rigoberto\"}",
|
||||
NameAgeEntity.class);
|
||||
NameCountriesEntity rigobertoCountriesAnalysis = om.readValue(
|
||||
"{\"country\":[{\"country_id\":\"MX\",\"probability\":0.132},{\"country_id\":\"PA\",\"probability\":0.107},{\"country_id\":\"CR\",\"probability\":0.09},{\"country_id\":\"HN\",\"probability\":0.082},{\"country_id\":\"GT\",\"probability\":0.075}],\"name\":\"Rigoberto\"}",
|
||||
NameCountriesEntity.class);
|
||||
NameGenderEntity rigobertoGenderAnalysis = om.readValue(
|
||||
"{\"count\":13927,\"gender\":\"male\",\"name\":\"Rigoberto\",\"probability\":1.0}",
|
||||
NameGenderEntity.class);
|
||||
Mockito.when(ageAnalysisService.getAgeAnalysisForName(nameToAnalyze))
|
||||
.thenReturn(ResponseEntity.ok(rigobertoAgeAnalysis));
|
||||
Mockito.when(countryAnalysisService.getCountryAnalysisForName(nameToAnalyze))
|
||||
.thenReturn(ResponseEntity.ok(rigobertoCountriesAnalysis));
|
||||
Mockito.when(genderAnalysisService.getGenderAnalysisForName(nameToAnalyze))
|
||||
.thenReturn(ResponseEntity.ok(rigobertoGenderAnalysis));
|
||||
|
||||
NameRequest rigobertoRequest = new NameRequest();
|
||||
rigobertoRequest.setName(nameToAnalyze);
|
||||
CompletableFuture<NameAnalysisEntity> result = toTest.searchForName(rigobertoRequest);
|
||||
|
||||
try {
|
||||
NameAnalysisEntity analysisResult = result.get();
|
||||
assertEquals(nameToAnalyze, analysisResult.getName());
|
||||
assertEquals(rigobertoAgeAnalysis, analysisResult.getAge());
|
||||
assertEquals(rigobertoCountriesAnalysis, analysisResult.getCountries());
|
||||
assertEquals(rigobertoGenderAnalysis, analysisResult.getGender());
|
||||
|
||||
} catch (Exception e) {
|
||||
fail("Not expected exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenNameAnalysisRequestFails_thenCompletableFutureException() {
|
||||
String nameToAnalyze = "Rigoberto";
|
||||
Mockito.when(ageAnalysisService.getAgeAnalysisForName(nameToAnalyze))
|
||||
.thenThrow(new RuntimeException("Failed age analysis for name"));
|
||||
Mockito.when(countryAnalysisService.getCountryAnalysisForName(nameToAnalyze))
|
||||
.thenThrow(new RuntimeException("Failed country analysis for name"));
|
||||
Mockito.when(genderAnalysisService.getGenderAnalysisForName(nameToAnalyze))
|
||||
.thenThrow(new RuntimeException("Failed gender analysis for name"));
|
||||
|
||||
NameRequest rigobertoRequest = new NameRequest();
|
||||
rigobertoRequest.setName(nameToAnalyze);
|
||||
CompletableFuture<NameAnalysisEntity> result = toTest.searchForName(rigobertoRequest);
|
||||
|
||||
try {
|
||||
result.get();
|
||||
fail("Expected Execution Exception");
|
||||
|
||||
} catch (ExecutionException e) {
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
fail("Expected Execution Exception");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
spring.http.encoding.enabled=true
|
||||
spring.devtools.add-properties=false
|
||||
logging.level.web=DEBUG
|
||||
spring.thymeleaf.check-template-location=false
|
|
@ -0,0 +1,29 @@
|
|||
<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/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung.spring-thymeleaf-attributes</groupId>
|
||||
<artifactId>spring-thymeleaf-attributes-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<modules>
|
||||
<module>accessing-session-attributes</module>
|
||||
</modules>
|
||||
</project>
|
Loading…
Reference in New Issue