2016-03-21 8 views
0

私はThreadLocalを含んで基底クラスがあります。取得THREADLOCALは()メソッドが呼び出されていないセット予期しない結果を()与え

@Singleton 
public class BaseView extends HttpServlet { 

protected ThreadLocal<Locale> locale = new ThreadLocal<Locale>(); 

private Locale getLocale() { 
    return (Locale) ObjectUtils.defaultIfNull(locale.get(), Locale.ENGLISH); 
} 

... 

} 

そして、EmailValidatedViewに拡張されています

はトークンが
@Singleton 
public class EmailValidatedView extends BaseView { 

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    String token = req.getParameter("token"); 
    if (token != null) { 
     try { 
      User user = userService.validateEmail(token); 
      locale.set(user.parseLocale()); 
     } catch (ServiceException e) { 
      e.printStackTrace(); 
     } 
    } 
    sendResponse("validatedEmail.vm", resp.getWriter(), $()); 
} 
} 

のときを無効、私はServiceExceptionを取得し、ロケールは設定されていません。この場合、sendResponse()メソッドはデフォルトロケール(英語)を使用する必要があります。しかし、無効なトークンでブラウザの同じページをリフレッシュすると、毎回異なる/関連しない言語が表示されることがあります。それはなぜ起こるのですか?

+2

なぜこのためにThreadLocalを使用していますか? –

+0

HttpServetは@Singletonでアノテーションされているので、ロケールはスレッドセーフであるか、またはメソッドの引数として渡されるべきです。http://stackoverflow.com/a/10665256/5962766 – Justas

+0

try-catchの上にデフォルトのロケールを設定すると、問題が解決します。 – Justas

答えて

1

ほとんどのHTTPサーバーは、プールのスレッドを再利用します。スレッドセーフな設定を維持することは良いことです.SteleLocalが役立ちますが、あなたのロケールがリクエストごとにリセットされないようにロジックが構成されています。したがって、過去のリクエストからのスレッドの古いロケールが流出することは驚くことではありません。

新しいロケールごとに、ロケールが読み込まれるごとにロケールが設定され、デフォルトのロケールが設定されている(つまり、ThreadLocalの値がクリアされる)ことを確認する必要があります。

関連する問題