Lokalizacja komunikatów w Springu.

0

Witam. W swoim projekcie Springowym mam problem z lokalizacją komunikatów, wyświetlanych na stronie. Mam taki formularz:

	<form:form action="addAdmin" modelAttribute="user" method="post">
		<form:label path="username">Login: </form:label>
		<form:input path="username" />
		<form:errors path="username" cssClass="error" />
		<br />
		<form:label path="password">Hasło: </form:label>
		<form:password path="password" />
		<form:errors path="password" cssClass="error" />
		<br />
		<form:label path="firstName">Imię: </form:label>
		<form:input path="firstName" />
		<form:errors path="firstName" cssClass="error" />
		<br />
		<form:label path="lastName">Nazwisko: </form:label>
		<form:input path="lastName" />
		<form:errors path="lastName" cssClass="error" />
		<br />
		<form:label path="email">Email: </form:label>
		<form:input path="email" />
		<form:errors path="email" cssClass="error" />
		<br />
		<input type="submit" value="Dodaj" />
	</form:form> 

Ale niestety komunikaty nadal są po angielsku, a chciałem je zlokalizować na język polski. W tym celu utworzyłem plik messages_pl_PL.properties:

javax.validation.constraints.NotNull.message=Wartosc nie moze byc null

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets 
		and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		/WEB-INF/spring/root-context.xml
		/WEB-INF/spring/security-config.xml
		</param-value>

	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
			/WEB-INF/spring/appServlet/servlet-context.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>
 

servlet-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<tx:annotation-driven transaction-manager="transactionManager" />

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->
	<context:component-scan base-package="pl.piotr.ibank" />

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<beans:bean id="messageSource"
		class="org.springframework.context.support.ResourceBundleMessageSource">
		<beans:property name="basename" value="messages" />
	</beans:bean>

	<beans:bean id="localeResolver"
		class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
		<beans:property name="defaultLocale" value="pl_PL" />
	</beans:bean>

</beans:beans>
 

Plik wrzuciłem do folderu webapp/resources. Ale komunikaty nadal są po angielsku i dostaję warning na serwerze:

WARN : org.springframework.context.support.ResourceBundleMessageSource - ResourceBundle [messages] not found for MessageSource: Can't find bundle for base name messages, locale pl_PL

Gdzieś doczytałem, że ten plik jeszcze należy wrzucić do folderu classes więc przerzuciłem go też do WEB-INF/classes. Warning z serwera zniknął, ale errory nadal są po angielsku.

0

Zmodyfikowałem ten servlet-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<tx:annotation-driven transaction-manager="transactionManager" />

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->
	<context:component-scan base-package="pl.piotr.ibank" />

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<beans:bean id="messageSource"
		class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<beans:property name="basename" value="classpath:i18n/messages" />
		<beans:property name="defaultEncoding" value="UTF-8" />
	</beans:bean>

	<beans:bean id="localeResolver"
		class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
		<beans:property name="defaultLocale" value="pl_PL" />
	</beans:bean>

	<interceptors>
		<beans:bean id="localeChangeInterceptor"
			class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
			<beans:property name="paramName" value="lang" />
		</beans:bean>
	</interceptors>

</beans:beans>
 

Nawet wrzuciłęm swój plik messages_pl_PL.properties do folderu i18n żeby było tak jak tam, ale nadal nie działa.

0

Screenshot drzewa katalogów plz :)

0
Shalom napisał(a):

Screenshot drzewa katalogów plz :)

http://zapodaj.net/97c344a2e77d5.png.html

1

Ale tak właściwie to jak wygląda ten twój formularz? Bo nie widze w tym powyżej żadnego

<spring:message code="nazwa.property"/>

Więc jak to jest?

0
<form:errors path="username" cssClass="error" />

Wyświetla błędy.

1

No ale co ma jedno do drugiego? Przecież błędy są wiązane do walidowanego beana. A jak niby wiążesz sobie te properties z beanem?

0

Dobra już zaskoczyłem o co chodzi. Działa to jak wrzucę np.

<spring:message code="User.firstName" />

a w messages_pl_PL.properties mam:

User.firstName=Podaj 1 imie
to mi to wyświetla. Ale jak to połączyć z errorem?

<form:errors path="firstName" cssClass="error"
			<spring:message code="User.firstName" /> />

Takie coś nie działa. I widzę tutaj nie da się rozrurznić co ma wyświetlić dla firstName jak będzie puste a co jak przekroczy założony limit np 20 znaków, tylko zawsze wyświetli to sam co podpisane pod User.firstName.

Znalazłem taki sposób i on działa ok, tylko nie wiem czy takie coś jest powszechne. W klasie encyjnej wrzucać wiadomości dla błędów:

	@NotBlank(message = "Podaj imię")
	@NotNull
	@Size(min = 3, max = 20, message = "Imię musi mieć minimum 3 i maksium 20 znaków")
	@Column(name = "firstName") 

Ja chciałem zlokalizować te ogólne komunikaty:

javax.validation.constraints.AssertFalse.message=must be false
javax.validation.constraints.AssertTrue.message=must be true
javax.validation.constraints.DecimalMax.message=must be less than or equal to {value}
javax.validation.constraints.DecimalMin.message=must be greater than or equal to {value}
javax.validation.constraints.Digits.message=numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected)
javax.validation.constraints.Future.message=must be in the future
javax.validation.constraints.Max.message=must be less than or equal to {value}
javax.validation.constraints.Min.message=must be greater than or equal to {value}
javax.validation.constraints.NotNull.message=pole nie moze byc nullem
javax.validation.constraints.Null.message=must be null
javax.validation.constraints.Past.message=must be in the past
javax.validation.constraints.Pattern.message=must match "{regexp}"
javax.validation.constraints.Size.message=size must be between {min} and {max}
org.hibernate.validator.constraints.Email.message="{value}" is not a valid email address
org.hibernate.validator.constraints.Length.message=length must be between {min} and {max}
org.hibernate.validator.constraints.NotEmpty.message=pole nie moze byc puste
org.hibernate.validator.constraints.Range.message={value} must be between {min} and {max}

Ale jak to wrzucę przetłumaczone w messages_pl_PL.properties to nie działa.

1

Ech chłopie, naucz ty sie pisać konkretne tematy... Szukasz tego:
http://www.intertech.com/Blog/Spring-Framework-JSR-303-Validation-and-Custom-Messages/
czyli

@Min(value=0, message="A contact cannot have fewer than 0 children")
@Max(value=20, message="A contact cannot have more than 20 children")

i w messages

Min=Your entry is too small.
Max=Your entry is too large.

Ale robisz to źle. W OGÓLE nie powinieneś wysyłać do widoku obiektów encyjnych. To jest proszenie sie o guza. Za dużo widziałem takich błędów jak ktoś sobie modyfikował taki obiekt, żeby lepiej wyświetlić a potem się dziwił że mu sie w bazie wartości pozmieniały. Beany wysyłane do/z widoku powinny być osobnymi klasami.

0

Ok, dzięki. Z tym osobnym beanem takim jak klasa encyjna to mi przypomniałeś, że kiedyś coś takiego przeglądałem i znalazłem to: http://www.dineshonjava.com/2012/12/spring-mvc-with-hibernate-crud-example.html#.VHORS3GG8ts

Czyli chodzi tutaj o takie coś, że gość ma encje Employee i beana EmployeeBean i w kontrolerze jak przekazuje do widoku itp. to operuje na tym EmployeeBean a jak chce go przekonwertować przed zapisem do bazy to używa:

Employee employee = prepareModel(employeeBean);  

ma tam takie 3 metody na końcu EmployeeController.java, które zamieniają encje na beana itp. O to chodzi? Takie jest prawidłowy sposób? I jeszcze jedno pytanie do tego EmployeeBean nie trzeba dodawać adnotacji, żeby to był Bean Springowy? Np @Component

? Czy może to być zwykła klasa POJO Javy jak w tym tutku?
1

Generalnie tak, o to mi chodzi. Czy prawidłowy to kwestia gustu, ale generalnie bezpieczniejszy.
Czy ty w ogóle rozumiesz co to jest @Component? To jest adnotacja która mówi że Spring ma stworzyć singletonowy serwis z takiego obiektu. Gdzie tu jakiś sens żeby oznaczać takiego beana w ten sposób? o_O Twój bean powinien w kontrolerze być co najwyżej oznaczony jako @Valid i @ModelAttribute

1 użytkowników online, w tym zalogowanych: 0, gości: 1