Wie erhalte ich ein aktuelles Benutzergebietsschema von Spring, ohne es als Parameter an Funktionen zu übergeben?

70

Ich verwende Spring 3.1 und möchte herausfinden, dass das Gebietsschema für den aktuellen Benutzer aktiv ist. Gibt es eine Möglichkeit, das Gebietsschema direkt abzurufen, ohne gezwungen zu sein, es vom Controller an die Serviceschicht zu übergeben ... usw.

Speichert Spring das Gebietsschema in einem lokalen Thread-Speicher, in dem es durch Aufrufen einer statischen Methode abgerufen werden kann?

ams
quelle

Antworten:

153

Ich habe auch gesucht, wie ich auf das Gebietsschema zugreifen kann, ohne es herumzugeben Locale, aber ich bin noch ziemlich neu in Spring und fand die meisten Lösungen verwirrend. Es stellt sich jedoch heraus, dass Spring MVC das Gebietsschema im lokalen Thread-Speicher speichert. Es kann erreicht werden durch:

Locale locale = LocaleContextHolder.getLocale();

Der letzte Ansatz [...] basiert auf einem lokalen Thread, um das aktuelle Gebietsschema in einer beliebigen Entität Ihrer Architektur bereitzustellen. [...] Sie müssen sich bewusst sein, dass der Inhalt des LocaleContextHolder standardmäßig dem in der Webanforderung angegebenen Gebietsschema entspricht.

Von: Konfigurieren der Gebietsschemaumschaltung mit Spring MVC 3 . (Dieser Beitrag bietet auch alternative Konfigurationen / Methoden zum Abrufen des Gebietsschemas, die für alle nützlich sein können, die dies tun möchten.)

Sie können auch die Ansicht LocaleContextHolderdocs von Frühling hier .

Sam Routledge
quelle
1
Auch für mich gearbeitet, hier ist die Methodenliste von LocaleContextHolder docs.spring.io/spring/docs/current/javadoc-api/org/…
Federico Traiman
5

Es hängt davon ab, wo Sie das Gebietsschema in einer Sitzung oder in einem Cookie gespeichert haben.

In meiner Anwendung habe ich konfiguriert, dass das Benutzergebietsschema in seiner Sitzung mit der unten angegebenen Konfiguration gespeichert wird.

    <mvc:interceptors>
        <ref bean="localeChangeInterceptor"/>
    </mvc:interceptors>

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

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

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
        <list>
            <value>/WEB-INF/i18n/labels</value>
            <value>/WEB-INF/i18n/messages</value>
            <value>/WEB-INF/i18n/include</value>
        </list>
        </property>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

Wenn Sie so etwas getan haben, können Sie den Gebietsschema-Parameter einfach aus der Sitzung abrufen.

Hoffe das hilft dir.

Prost.

Japan Trivedi
quelle
Japs, das hilft mir nicht, weil ich das Gebietsschema innerhalb eines Dienstes kennen und das Gebietsschema nicht an die Dienstmethode übergeben möchte. Ich möchte in der Lage sein, eine statische Funktion aufzurufen und das aktuelle Gebietsschema für den Benutzer als abzurufen Wird von dem konfigurierten Gebietsschema-Resolver gelöst. Normalerweise können Sie einem Annotation-Controller nur einen Parameter vom Typ "Gebietsschema" definieren. Dadurch wird das Gebietsschema aufgelöst. Ich möchte den Gebietsschemaparameter nicht auf die untere Ebene verschieben. Ich möchte ihn nur aus einem Thread-Gebietsschema abrufen.
Ams
In diesem Fall können Sie auch die localeResolver-Bean in Ihrem Dienst als automatisch verdrahtet abrufen und anschließend die Klassenmethode aufrufen, um das aktuelle Gebietsschema zu bestimmen, das vom Benutzer in der Sitzung festgelegt wurde.
Japan Trivedi
Das Injizieren des LocaleResolver funktioniert nicht, da für den LocaleResolver der Zugriff auf httpServletRequest oder Response erforderlich ist, sodass ich diese an die Service-Layer weitergeben müsste, was ich nicht tun möchte.
Ams
In diesem Fall bleibt keine andere Wahl, als das Gebietsschema im Controller abzurufen und es dann als Argument an den Dienst zu übergeben. Ich sehe keine anderen Möglichkeiten, wie Sie das Gebietsschema wollen.
Japan Trivedi
2

Wir hatten das gleiche Bedürfnis, so kamen mit Aufstellen Localein ThreadLocalZusammenhang. Wir hatten bereits ein Objekt (einige Benutzerinformationen) im ThreadLocalKontext gespeichert , also haben wir es einfach angehängt (sieht aus wie ein Hack, aber die schnellste Lösung, die wir gefunden haben).

Erikas Zuzevicius
quelle
6
Genau das LocaleContextHolderbewirkt: Speichern Localein einer ThreadLocalVariablen. Sie müssen keinen benutzerdefinierten Hack verwenden (da Spring diesen Hack bereits für Sie ausführt).
cr7pt0gr4ph7