参考( TERASOLUNA Server Framework for Java (5.x) on Accel Platform アーキテクチャ )¶
TERASOLUNA Server Framework for Java (5.x) (http://terasolunaorg.github.io/) は、Spring Framework (http://projects.spring.io/spring-framework/) をベースに構成されるJavaフレームワークです。TERASOLUNA Server Framework for Java (5.x) の詳細については TERASOLUNA Server Framework for Java (5.x) Development Guideline にて公開されています。本項では、 intra-mart Accel Platform と TERASOLUNA Server Framework for Java (5.x) によるフルスタックフレームワークについて説明します。
TERASOLUNA Server Framework for Java (5.x) on Accel Platform アーキテクチャ
TERASOLUNA Server Framework for Java (5.x) on Accel Platform の構成¶
intra-mart Accel Platform 上に TERASOLUNA Server Framework for Java (5.x) を組み込んだ「フルスタックフレームワーク」のイメージは下図の通りです。
TERASOLUNA Server Framework for Java (5.x) は、下記の通り、Spring Framework がベースで構成され、トランザクショントークンチェック、コードリスト、例外ハンドリングやロギング等の機能を提供し、その活用方法を「 TERASOLUNA Server Framework for Java (5.x) Development Guideline 」として提供しています。
アプリケーション層 Spring MVC / Bean Validation ドメイン層 Spring Framework インフラストラクチャ層 MyBatis3 TERASOLUNA Server Framework for Java (5.x) on Accel Platform では、intra-mart Accel Platform が提供する以下の機能を利用して、TERASOLUNA Server Framework for Java (5.x) のアプリケーションを効率よく開発することができます。
- 認可
- アクセスコンテキスト
- 認証機能
- 国際化
- データベース
- ログ
- UI(デザインガイドライン)
- UI(スマートフォン開発ガイドライン)
- エラー処理
- Storage
- 非同期処理
- ジョブスケジューラ
- Lockサービス
- Cacheサービス
- ショートカットアクセス機能
- ポートレット
- IM-Workflow
- etc...
コラム
intra-mart Accel Platform が提供する各機能の使い方については上記リンクより参照にしてください。
TERASOLUNA Server Framework for Java (5.x) との対応¶
TERASOLUNA Server Framework for Java (5.x) Development Guideline で想定している TERASOLUNA Server Framework for Java (5.x) のアーキテクチャの TERASOLUNA Server Framework for Java (5.x) on Accel Platform 上での対応は以下の通りです。
機能 対応 備考 データアクセス(共通編) シンプルなCRUD操作で動作確認を行っております。 データアクセス(JPA編) intra-mart Accel Platform では対応していません。 データアクセス(Mybatis3編) シンプルなCRUD操作で動作確認を行っております。 排他制御 入力チェック ロギング Logger, MDCは intra-mart Accel Platform のものを使用してください。 また、 「ログ」を参照してください。 TraceLoggingInterceptor, ExceptionLoggerについては、 「TERASOLUNA Server Framework for Java (5.x) Development Guideline」を参照してください。 例外ハンドリング セッション管理 Spring Securityを使うものについては対象外です。 メッセージ管理 IntramartMessageSource を使用してください。 また、「多言語化されたメッセージを取得する」を参照してください。 プロパティ管理 ページネーション imuiTableを使用してください。 二重送信防止 国際化 IntramartMessageSource, AccountLocaleResolverを使用してください。 また、「国際化」を参照してください。 コードリスト Bean定義 applicationContext-im_tgfw_web.xml にコードリストの設定を記述しています。 <mvc:mapping>のpath属性は、適用対象のパスを設定してください。 Ajax RESTful Web Service @RestControllerの代わりにWeb API Makerを使用してください。 service層は、applicationContextからbeanを取得してください。 Web API Makerについては「Web API Maker プログラミングガイド」を参照してください。 RESTクライアント(HTTPクライアント) SOAP Web Service(サーバ/クライアント) 「Webサービス Java開発プログラミングガイド」を参照してください。 ファイルアップロード Servlet 3.0の機能は非対応です。 multipartResolverにはCommonsMultipartResolverを設定しています。 また、「Storage」を参照してください。 ファイルダウンロード 「Storage」を参照してください。 E-mail送信(SMTP) Tiles intra-mart Accel Platform のテーマ機能を使用してください。 システム時刻 org.terasoluna.gfw.common.date.JdbcAdjustedDateFactory を使用する場合、 dataSourceプロパティにはシェアードデータソースを指定してください。 シェアードデータソースの設定は、 「DataSource」や 「データベース」を参照してください。 ユーティリティ(dozer) ユーティリティ(joda time) TERASOLUNA Server Framework for Java (5.x) Development Guideline に記載されている TERASOLUNA Server Framework for Java (5.x) のセキュリティ対策についての TERASOLUNA Server Framework for Java (5.x) on Accel Platform 上での対応は以下の通りです。
セキュリティ対策 対応 備考 Spring Security (認証、パスワードハッシュ化、認可) 認証、パスワードハッシュ化、認可機能については、 intra-mart Accel Platform の認証、認可を使用してください。 intra-mart Accel Platform でもパスワードのハッシュ化を行っています。 XSS対策 CSRF対策 intra-mart Accel PlatformのimSecureTokenタグを使用してください。 「imSecureTokenタグ」、「CSRF対策」を参照してください。
TERASOLUNA Server Framework for Java (5.x) on Accel Platform におけるBean定義の既定値¶
Spring MVC では、DispatcherServlet というサーブレットクラスが提供されています。DispatcherServletは、クライアントからの要求に対して、要求情報からコントローラを探し、コントローラを呼び出す役割を担います。intra-mart Accel Platform では、クライアントからの要求に対して、該当するプログラムを探し、認可のチェックをし、見つかったプログラムを呼び出す「ルーティング機構」があります。intra-mart Accel Platform では、この「ルーティング機構」からSpring MVCのコントローラを呼び出す機構が組み込まれています。コラム
「ルーティング機構」の仕組みについては、「認可」ページを参考にしてください。Spring MVCでは通常、1つのWebアプリケーションに複数のDispatcherServletを登録し、サーブレットごとにBean定義を行うことができますが、intra-mart Accel Platform では、DispatcherServletを拡張したサーブレットクラスが1つだけ登録されており、このサーブレットクラスを複数登録することはできません。そのため、intra-mart Accel Platform ではすべてのBean定義はWebアプリケーション上で共有されることになります。intra-mart Accel Platform では、あらかじめ下記ファイルにてBean定義が行われています。
- <Jugglingプロジェクト>/classes/META-INF/spring/applicationContext-im_tgfw_common.xml
- <Jugglingプロジェクト>/classes/META-INF/spring/applicationContext-im_tgfw_web.xml
- <Jugglingプロジェクト>/classes/META-INF/spring/SpringMVCServlet-servlet.xml
- <Jugglingプロジェクト>/classes/META-INF/spring/applicationContext-im_tgfw_mybatis3.xml
これらのBean定義は、intra-mart Accel Platform のテナント上で共有されるため、セットアップガイドに記載のない内容以外は基本変更しないようにしてください。以下、intra-mart Accel Platform へのSpring MVCの組込み内容と上記Bean定義ファイルの初期値について示します。
web.xml¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" metadata-complete="false" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> : (省略) <!-- Web アプリケーション起動時に、クラスパス上の/META-INF/spring/内のapplicationContextで始まるBean定義ファイルをロード させる設定--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/META-INF/spring/applicationContext*.xml</param-value> </context-param> <listener> <listener-class>jp.co.intra_mart.framework.extension.spring.web.servlet.SpringServletContextListener</listener-class> </listener> : (省略) <!-- 「ルーティング機構」用にDispatcherServletを拡張したサーブレットを登録 --> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>jp.co.intra_mart.framework.extension.spring.web.servlet.IntramartDispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/META-INF/spring/SpringMVCServlet-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <multipart-config/> </servlet> : (省略) </web-app>
applicationContext-im_tgfw_common.xml¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- a bean which holds the root application context --> <bean class="jp.co.intra_mart.system.extension.spring.context.ApplicationContextHolder" /> <!-- message source which loads from 'WEB-INF/conf/message/**/*.properties' --> <bean id="messageSource" class="jp.co.intra_mart.framework.extension.spring.message.IntramartMessageSource" /> <!-- bean validation (JSR-303 / JSR-349) --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="validationMessageSource" ref="messageSource" /> </bean> <!-- transaction manager (JTA) --> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> <!-- enable the configuration of transactional behavior based on annotations --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- intra-mart tenant datasource --> <bean id="dataSource" class="jp.co.intra_mart.framework.extension.spring.datasource.TenantDataSource" /> <!-- intra-mart shared datasource --> <!-- [Note] If you use the shared datasource, please uncomment/enable the following setting and set the bean's id and the connectId's value. --> <!-- <bean id="sharedDataSource" class="jp.co.intra_mart.framework.extension.spring.datasource.SharedDataSource"> <constructor-arg name="connectId" value="xxxxxxxxxxxxxx" /> </bean> --> <!-- property placeholder setting --> <context:property-placeholder location="classpath*:/META-INF/spring/*.properties" /> <!-- dozer setting --> <!-- <bean class="org.dozer.spring.DozerBeanMapperFactoryBean"> <property name="mappingFiles" value="classpath*:/META-INF/dozer/**/*-mapping.xml" /> </bean> --> <!-- Exception Code Resolver. --> <bean id="exceptionCodeResolver" class="org.terasoluna.gfw.common.exception.SimpleMappingExceptionCodeResolver"> <!-- Setting and Customization by project. --> <property name="exceptionMappings"> <map> <entry key="ResourceNotFoundException" value="w.im.fw.0001" /> <entry key="InvalidTransactionTokenException" value="w.im.fw.0004" /> <entry key="InvalidSecureTokenException" value="w.im.fw.0005" /> <entry key="BusinessException" value="w.im.fw.0002" /> </map> </property> <property name="defaultExceptionCode" value="e.im.fw.0001" /> </bean> <!-- Exception Logger. --> <bean id="exceptionLogger" class="org.terasoluna.gfw.common.exception.ExceptionLogger"> <property name="exceptionCodeResolver" ref="exceptionCodeResolver" /> </bean> </beans>
applicationContext-im_tgfw_web.xml¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- locale resolver --> <bean id="localeResolver" class="jp.co.intra_mart.framework.extension.spring.web.servlet.i18n.AccountLocaleResolver" /> <!-- SpringMVCRoute needs HandlerSelector bean. --> <bean id="handlerSelector" class="jp.co.intra_mart.system.router.spring.HandlerSelector" init-method="init" /> <!-- view components --> <context:component-scan base-package="jp.co.intra_mart.framework.extension.spring.web.servlet.view" /> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="0" /> </bean> <!-- prefix for InternalResourceViewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="order" value="1" /> </bean> <!-- multipart resolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> <!-- support for annotation-driven MVC controllers --> <mvc:annotation-driven conversion-service="conversionService"> <!-- transaction token --> <mvc:argument-resolvers> <bean class="org.terasoluna.gfw.web.token.transaction.TransactionTokenContextHandlerMethodArgumentResolver" /> </mvc:argument-resolvers> <!-- jackson message converter --> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="jp.co.intra_mart.framework.extension.spring.http.converter.json.AccountDateObjectMapper" /> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="jp.co.intra_mart.framework.extension.spring.format.datetime.AccountDateFormatAnnotationFormatterFactory"/> <bean class="jp.co.intra_mart.framework.extension.spring.format.datetime.AccountDateTimeFormatAnnotationFormatterFactory"/> <bean class="jp.co.intra_mart.framework.extension.spring.format.datetime.AccountTimeFormatAnnotationFormatterFactory"/> </set> </property> </bean> <!-- MVC interceptors --> <mvc:interceptors> <!-- transaction token --> <mvc:interceptor> <mvc:mapping path="/**" /> <!-- configure the path to specify the package of controllers. --> <bean class="org.terasoluna.gfw.web.token.transaction.TransactionTokenInterceptor"> <constructor-arg value="10" /> </bean> </mvc:interceptor> <!-- code list --> <mvc:interceptor> <mvc:mapping path="/**" /> <!-- configure the path to specify the package of controllers. --> <bean class="org.terasoluna.gfw.web.codelist.CodeListInterceptor"> <property name="codeListIdPattern" value="CL_.+" /> </bean> </mvc:interceptor> </mvc:interceptors> <!-- transaction token --> <bean name="requestDataValueProcessor" class="org.terasoluna.gfw.web.mvc.support.CompositeRequestDataValueProcessor"> <constructor-arg> <util:list> <bean class="org.terasoluna.gfw.web.token.transaction.TransactionTokenRequestDataValueProcessor" /> </util:list> </constructor-arg> </bean> <!-- secure token validator --> <bean id="secureTokenValidator" class="jp.co.intra_mart.framework.extension.spring.web.csrf.SecureTokenValidator" /> <!-- Setting Exception Handling. --> <!-- Exception Resolver. --> <bean class="org.terasoluna.gfw.web.exception.SystemExceptionResolver"> <property name="exceptionCodeResolver" ref="exceptionCodeResolver" /> <!-- Setting and Customization by project. --> <property name="order" value="3" /> <property name="exceptionMappings"> <map> <entry key="ResourceNotFoundException" value="im_tgfw/common/error/resourceNotFoundError.jsp" /> <entry key="BusinessException" value="im_tgfw/common/error/businessError.jsp" /> <entry key="InvalidTransactionTokenException" value="im_tgfw/common/error/transactionTokenError.jsp" /> <entry key="InvalidSecureTokenException" value="im_tgfw/common/error/secureTokenError.jsp" /> </map> </property> <property name="statusCodes"> <map> <entry key="im_tgfw/common/error/resourceNotFoundError" value="404" /> <entry key="im_tgfw/common/error/businessError" value="200" /> <entry key="im_tgfw/common/error/transactionTokenError" value="409" /> <entry key="im_tgfw/common/error/secureTokenError" value="403" /> </map> </property> <property name="defaultErrorView" value="im_tgfw/common/error/systemError.jsp" /> <property name="defaultStatusCode" value="500" /> </bean> <!-- AOP. --> <bean id="handlerExceptionResolverLoggingInterceptor" class="org.terasoluna.gfw.web.exception.HandlerExceptionResolverLoggingInterceptor"> <property name="exceptionLogger" ref="exceptionLogger" /> </bean> <aop:config> <aop:advisor advice-ref="handlerExceptionResolverLoggingInterceptor" pointcut="execution(* org.springframework.web.servlet.HandlerExceptionResolver.resolveException(..))" /> </aop:config> </beans>
SpringMVCServlet-servlet.xml¶
1 2 3 4 5 6 7 8 9 10 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> </beans>
applicationContext-im_tgfw_mybatis3.xml¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:/META-INF/mybatis/mybatis-config.xml" /> </bean> <!-- setting 'base-package' which is the package in which mapper interface is. --> <!-- <mybatis:scan base-package="xxxxxx.yyyyyy.zzzzzz.domain.repository" /> --> </beans>