Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e175905

Browse files
Spring MVC - Thymeleaf i18n
Soporte para varios idiomas en una aplicacion web.
1 parent c48b191 commit e175905

File tree

11 files changed

+401
-0
lines changed

11 files changed

+401
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project-shared-configuration>
3+
<!--
4+
This file contains additional configuration written by modules in the NetBeans IDE.
5+
The configuration is intended to be shared among all the users of project and
6+
therefore it is assumed to be part of version control checkout.
7+
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
8+
-->
9+
<spring-data xmlns="http://www.netbeans.org/ns/spring-data/1">
10+
<config-files>
11+
<config-file>src/main/webapp/WEB-INF/springmvc-servlet.xml</config-file>
12+
</config-files>
13+
<config-file-groups/>
14+
</spring-data>
15+
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
16+
<!--
17+
Properties that influence various parts of the IDE, especially code formatting and the like.
18+
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
19+
That way multiple projects can share the same settings (useful for formatting rules for example).
20+
Any value defined here will override the pom.xml file value but is only applicable to the current project.
21+
-->
22+
<org-netbeans-modules-javascript2-requirejs.enabled>true</org-netbeans-modules-javascript2-requirejs.enabled>
23+
</properties>
24+
</project-shared-configuration>

‎tutorial_webmvc_thymeleaf_i18n/pom.xml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>carmelo.spring</groupId>
5+
<artifactId>tutorial_webmvc_thymeleaf_i18n</artifactId>
6+
<packaging>war</packaging>
7+
<version>1.0</version>
8+
<name>tutorial_webmvc_thymeleaf_i18n</name>
9+
10+
<properties>
11+
<spring.version>4.3.7.RELEASE</spring.version>
12+
<thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<maven.compiler.source>1.8</maven.compiler.source>
15+
<maven.compiler.target>1.8</maven.compiler.target>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.springframework</groupId>
21+
<artifactId>spring-webmvc</artifactId>
22+
<version>${spring.version}</version>
23+
</dependency>
24+
25+
<dependency>
26+
<groupId>org.thymeleaf</groupId>
27+
<artifactId>thymeleaf-spring4</artifactId>
28+
<version>${thymeleaf.version}</version>
29+
<scope>compile</scope>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>org.hibernate</groupId>
34+
<artifactId>hibernate-validator</artifactId>
35+
<version>5.3.4.Final</version>
36+
</dependency>
37+
38+
<dependency>
39+
<groupId>javax</groupId>
40+
<artifactId>javaee-web-api</artifactId>
41+
<version>7.0</version>
42+
</dependency>
43+
</dependencies>
44+
45+
<build>
46+
<finalName>tutorial_webmvc_thymeleaf_i18n</finalName>
47+
<plugins>
48+
<plugin>
49+
<groupId>org.apache.maven.plugins</groupId>
50+
<artifactId>maven-war-plugin</artifactId>
51+
<version>2.3</version>
52+
<configuration>
53+
<failOnMissingWebXml>false</failOnMissingWebXml>
54+
</configuration>
55+
</plugin>
56+
</plugins>
57+
</build>
58+
59+
</project>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package carmelo.spring.config;
2+
3+
import org.springframework.beans.BeansException;
4+
import org.springframework.context.ApplicationContext;
5+
import org.springframework.context.ApplicationContextAware;
6+
import org.springframework.context.MessageSource;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.ComponentScan;
9+
import org.springframework.context.annotation.Configuration;
10+
import org.springframework.context.support.ResourceBundleMessageSource;
11+
import org.springframework.web.servlet.LocaleResolver;
12+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
13+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
14+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
15+
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
16+
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
17+
import org.thymeleaf.spring4.SpringTemplateEngine;
18+
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
19+
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
20+
21+
@EnableWebMvc
22+
@Configuration
23+
@ComponentScan(basePackages = {"carmelo.spring.controller"})
24+
public class WebAppConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
25+
26+
private ApplicationContext applicationContext;
27+
28+
@Override
29+
public void setApplicationContext(ApplicationContext ac) throws BeansException {
30+
this.applicationContext = ac;
31+
}
32+
33+
@Bean
34+
public MessageSource messageSource() {
35+
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
36+
messageSource.setBasename("messages");
37+
return messageSource;
38+
}
39+
40+
@Bean
41+
public LocaleResolver localeResolver() {
42+
return new SessionLocaleResolver();
43+
}
44+
45+
@Bean
46+
public LocaleChangeInterceptor localeChangeInterceptor() {
47+
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
48+
localeChangeInterceptor.setParamName("lang");
49+
return localeChangeInterceptor;
50+
}
51+
52+
@Override
53+
public void addInterceptors(InterceptorRegistry registry) {
54+
registry.addInterceptor(localeChangeInterceptor());
55+
}
56+
57+
@Bean
58+
public SpringResourceTemplateResolver templateResolver() {
59+
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
60+
templateResolver.setApplicationContext(this.applicationContext);
61+
templateResolver.setPrefix("/WEB-INF/templates/");
62+
templateResolver.setSuffix(".html");
63+
return templateResolver;
64+
}
65+
66+
@Bean
67+
public SpringTemplateEngine templateEngine() {
68+
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
69+
templateEngine.setTemplateResolver(templateResolver());
70+
templateEngine.setEnableSpringELCompiler(true);
71+
return templateEngine;
72+
}
73+
74+
@Bean
75+
public ThymeleafViewResolver viewResolver() {
76+
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
77+
viewResolver.setTemplateEngine(templateEngine());
78+
return viewResolver;
79+
}
80+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package carmelo.spring.config;
2+
3+
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
4+
5+
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
6+
7+
@Override
8+
protected Class<?>[] getRootConfigClasses() {
9+
return null;
10+
}
11+
12+
@Override
13+
protected Class<?>[] getServletConfigClasses() {
14+
return new Class[]{WebAppConfig.class};
15+
}
16+
17+
@Override
18+
protected String[] getServletMappings() {
19+
return new String[]{"/"};
20+
}
21+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package carmelo.spring.controller;
2+
3+
import carmelo.spring.model.Usuario;
4+
import javax.validation.Valid;
5+
import org.springframework.stereotype.Controller;
6+
import org.springframework.ui.Model;
7+
import org.springframework.validation.BindingResult;
8+
import org.springframework.web.bind.annotation.RequestMapping;
9+
import org.springframework.web.servlet.ModelAndView;
10+
11+
@Controller
12+
@RequestMapping("/user")
13+
public class UsuarioController {
14+
15+
@RequestMapping("/form")
16+
public String showUserForm(Model model){
17+
model.addAttribute("usuario", new Usuario());
18+
return "userForm";
19+
}
20+
21+
@RequestMapping("/create")
22+
public ModelAndView createUser(@Valid Usuario user, BindingResult result) {
23+
ModelAndView model = new ModelAndView();
24+
model.addObject("usuario", user);
25+
model.setViewName(result.hasErrors() ? "userForm" : "userReady");
26+
return model;
27+
}
28+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package carmelo.spring.model;
2+
3+
import javax.validation.constraints.Min;
4+
import javax.validation.constraints.NotNull;
5+
import javax.validation.constraints.Pattern;
6+
import javax.validation.constraints.Size;
7+
import org.hibernate.validator.constraints.Email;
8+
import org.hibernate.validator.constraints.NotBlank;
9+
10+
public class Usuario {
11+
12+
@Size(min = 3, max = 20, message = "el nombre debe tener mas de 3 letras y menos de 20.")
13+
private String nombre;
14+
15+
@NotBlank(message = "debe indicar el apellido del usuario.")
16+
private String apellido;
17+
18+
@Email
19+
@NotBlank
20+
private String correo;
21+
22+
@Pattern(regexp = "^[a-zA-Z]\\w{3,14}$", message = "debe contener letras seguidos de numeros")
23+
private String password;
24+
25+
@Min(value = 18, message = "el usuario debe tener 18+")
26+
@NotNull
27+
private Integer edad;
28+
29+
@NotNull
30+
private Boolean sexo;
31+
32+
public String getNombre() {
33+
return nombre;
34+
}
35+
36+
public void setNombre(String nombre) {
37+
this.nombre = nombre;
38+
}
39+
40+
public String getApellido() {
41+
return apellido;
42+
}
43+
44+
public void setApellido(String apellido) {
45+
this.apellido = apellido;
46+
}
47+
48+
public String getCorreo() {
49+
return correo;
50+
}
51+
52+
public void setCorreo(String correo) {
53+
this.correo = correo;
54+
}
55+
56+
public String getPassword() {
57+
return password;
58+
}
59+
60+
public void setPassword(String password) {
61+
this.password = password;
62+
}
63+
64+
public Integer getEdad() {
65+
return edad;
66+
}
67+
68+
public void setEdad(Integer edad) {
69+
this.edad = edad;
70+
}
71+
72+
public Boolean getSexo() {
73+
return sexo;
74+
}
75+
76+
public void setSexo(Boolean sexo) {
77+
this.sexo = sexo;
78+
}
79+
80+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
form.user.nombre=User name
3+
form.user.apellido=Last name
4+
form.user.correo=Email
5+
form.user.edad=User age
6+
form.user.sexo=Gender
7+
form.user.pass=Password
8+
form.user.boton=Send...
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
form.user.nombre=Nombre del usuario
3+
form.user.apellido=Apellido materno y paterno
4+
form.user.correo=Correo electronico
5+
form.user.edad=Edad del usuario
6+
form.user.sexo=Eres hombre
7+
form.user.pass=Tu contrase\u00f1a
8+
form.user.boton=Enviar...
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Context antiJARLocking="true" path="/thymeleaf"/>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!DOCTYPE html>
2+
<html xmlns:th="http://www.thymeleaf.org">
3+
<head>
4+
<title>Tutorial Thymeleaf</title>
5+
<meta charset="UTF-8">
6+
7+
<style type="text/css">
8+
.errorfield {
9+
color: #ae1d1d;
10+
font-style: italic;
11+
font-weight: bold;
12+
border: 1px solid #ff0000;
13+
}
14+
15+
.errorblock{
16+
color: #000;
17+
background-color: #ffEEEE;
18+
border: 1px solid #ff0000;
19+
padding: 8px;
20+
margin: 16px;
21+
font-style: italic;
22+
}
23+
</style>
24+
25+
</head>
26+
<body>
27+
<h2>Registro de usuarios:</h2>
28+
29+
<div style="padding: 10px; border: 1px solid gray;">
30+
<a href="?lang=es">Spanish</a>
31+
<a href="?lang=en">English</a>
32+
</div>
33+
34+
<form th:action="@{/user/create}" th:object="${usuario}" method="post">
35+
36+
<div class="errorblock" th:if="${#fields.hasErrors('*')}">
37+
<ul>
38+
<li th:each="err : ${#fields.errors('*')}"
39+
th:text="${err}">Input is incorrect</li>
40+
</ul>
41+
</div>
42+
43+
<fieldset>
44+
<legend>Datos del usuario</legend>
45+
<table>
46+
<tr>
47+
<td><label th:text="#{form.user.nombre}">Nombre: </label></td>
48+
<td><input type="text" th:field="*{nombre}" th:errorclass="errorfield"/></td>
49+
</tr>
50+
<tr>
51+
<td><label th:text="#{form.user.apellido}">Apellido: </label></td>
52+
<td><input type="text" th:field="*{apellido}" th:errorclass="errorfield"/></td>
53+
</tr>
54+
<tr>
55+
<td><label th:text="#{form.user.correo}">Correo: </label></td>
56+
<td><input type="text" th:field="*{correo}" th:errorclass="errorfield"/></td>
57+
</tr>
58+
<tr>
59+
<td><label th:text="#{form.user.pass}">Password: </label></td>
60+
<td><input type="password" th:field="*{password}" th:errorclass="errorfield"/></td>
61+
</tr>
62+
<tr>
63+
<td><label th:text="#{form.user.edad}">Edad: </label></td>
64+
<td><input type="number" th:field="*{edad}" th:errorclass="errorfield"/></td>
65+
</tr>
66+
<tr>
67+
<td><label th:text="#{form.user.sexo}">Sexo: </label></td>
68+
<td><input type="checkbox" th:field="*{sexo}"/></td>
69+
</tr>
70+
<tr>
71+
<td>
72+
<button type="submit" th:text="#{form.user.boton}"></button>
73+
</td>
74+
</tr>
75+
</table>
76+
</fieldset>
77+
</form>
78+
</body>
79+
</html>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /