2013年1月5日土曜日

HttpServletRequestのthread内共有

ASP.NETを利用していると
static HttpContext HttpContext.Current からリクエスト情報を取得して
IPADDRESS等の情報をどこででも取得することができます

似たような意識でJavaで実装していると
どうしてもHttpServletRequestの取得でつまずいてしまいます。

そこで、スレッド毎に値を保持するThreadLocalを利用して
HttpServletRequest をスレッド内で参照できるようにします


private final static ThreadLocal<HttpServletRequest> servletRequests = new ThreadLocal<HttpServletRequest>();

public static void setServletRequest(HttpServletRequest request) {
    servletRequests.set(request);
}

public static HttpServletRequest getServletRequest() {
    return servletRequests.get();
}


もちろん非同期な実装では参照できなくなる(かな?)
リクエスト初期化時にセットする必要があります。
リクエスト終了後はガベージコレクション対象になります。

2013年1月4日金曜日

Logbackメモ


Logback を利用してログ出力しているのですが、
これまでサンプルのままだったのを少し見直しました。


次のような要件を満たすように変更、
1.レベルがエラーの場合にメールで送信する
2.ファイル出力、日毎、100M毎 にローリング


main/resource/logback.xml :

<?xml version="1.0"?>
 <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<configuration debug="true" scan="true" scanPeriod="30 seconds">

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>

    <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <smtpHost>smtp.gmail.com</smtpHost>
        <smtpPort>587</smtpPort>
        <STARTTLS>true</STARTTLS>
        <username>[YOUR_NAME]@gmail.com</username>
        <password>[YOUR_PASSWORD]</password>
        <to>[TO]</to> <!-- additional destinations are possible -->
        <from>[FROM]</from>
        <subject>TESTING: %logger{20} - %m</subject>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <charset>UTF-8</charset>
            <Pattern>[%-5level][%d{yyyy-MM-dd HH:mm:ss.SSS}] %class - %msg%n</Pattern>
        </layout>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logFile.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- keep 30 days' worth of history -->
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <Pattern>[%-5level][%d{yyyy-MM-dd HH:mm:ss.SSS}] %class - %msg%n</Pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
        <appender-ref ref="STDOUT" />
        <appender-ref ref="EMAIL" />
    </root>
</configuration>



SMTPAppenderを利用してメールを送信します。
サンプルではGMAILで送信する設定にしています。
メールで送信する場合はLevelFilterを利用してERRORの場合のみ送信するようにしています。
File出力に関しては、ここのサンプルのままです。


File出力がネックになりそうな場合は、下のAsyncAppenderをFileAppenderの
前に挟んでAsync処理にする。
SMTPはAsyncで送信されているようなので気にしない 。

  <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE" />
  </appender>



アクセスログを出力したい場合は、ここを参照する

2013年1月3日木曜日

jetty maven gzipフィルター適用

maven上のjetty plugin でgzip を適用する方法。
このあたりの内容です。

http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin#Using_GZip_Compression_and_Other_Jetty_Extensions


pom.xmlのプラグイン設定にdependancyを追加

<plugin>
       
<groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>                                        <version>8.1.8.v20121106</version>
         <configuration>
           [...]
       
</configuration>
         <dependencies> 
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-servlets</artifactId>
             <version>8.1.8.v20121106</version>
           </dependency>
         </dependencies>


web.xmlにgzipフィルターを定義

  <filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
    <init-param>
      <param-name>mimeTypes</param-name>
      <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>



pom.xmlにdependancyを追加していないと
ClassNotFoundExceptionで怒られます