参考( TERASOLUNA Server Framework for Java (5.x) for 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) for Accel Platform アーキテクチャ
TERASOLUNA Server Framework for Java (5.x) for 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) for 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) for Accel Platform 上での対応は以下の通りです。表中の記号は以下の意味を示します。: 対応、 : 注意点有り、 : 非対応
Webアプリ開発機能¶
機能 対応 備考 入力チェック 例外ハンドリング セッション管理 Spring Securityを使うものについては対象外です。 ページネーション imuiTableを使用してください。 二重送信防止 メッセージ管理 IntramartMessageSource を使用してください。 また、「多言語化されたメッセージを取得する」を参照してください。 国際化 IntramartMessageSource, AccountLocaleResolverを使用してください。 また、「国際化」を参照してください。 コードリスト Bean定義 applicationContext-im_tgfw_web.xml にコードリストの設定を記述しています。 <mvc:mapping>のpath属性は、適用対象のパスを設定してください。
JdbcCodeList を使用する場合、lazyInit プロパティに true を設定する必要があります。 設定例については下記の注意を参照してください。
ファイルアップロード Servlet 3.0の機能は非対応です。 multipartResolverにはCommonsMultipartResolverを設定しています。 また、「Storage」を参照してください。 ファイルダウンロード 「Storage」を参照してください。 Tiles intra-mart Accel Platform のテーマ機能を使用してください。 JSP Tag Library と EL Functions Ajax ヘルスチェック 注意
<bean id="CL_ZOO" class="org.terasoluna.gfw.common.codelist.JdbcCodeList"> <property name="dataSource" ref="dataSource" /> <property name="querySql" value="SELECT id, name FROM zzz_zoo ORDER BY id" /> <property name="valueColumn" value="id" /> <property name="labelColumn" value="name" /> <property name="lazyInit" value="true" /> </bean>
Web Service¶
機能 対応 備考 RESTful Web Service @RestControllerの代わりにWeb API Makerを使用してください。 service層は、applicationContextからbeanを取得してください。 Web API Makerについては「Web API Maker プログラミングガイド」を参照してください。 RESTクライアント(HTTPクライアント) SOAP Web Service(サーバ/クライアント) 「Webサービス Java開発プログラミングガイド」を参照してください。
データアクセス¶
機能 対応 備考 データアクセス(共通編) シンプルな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」を参照してください。 プロパティ管理 日付操作(JSR-310 Date and Time API) 日付操作(Joda Time) システム時刻 org.terasoluna.gfw.common.date.JdbcAdjustedDateFactory を使用する場合、 dataSourceプロパティにはシェアードデータソースを指定してください。 シェアードデータソースの設定は、 「DataSource」や 「データベース」を参照してください。 文字列処理 Beanマッピング(Dozer)
セキュリティ対策¶
Spring Security は非対応です。
セキュリティ対策 対応 備考 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) for 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 <?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx https://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="com.github.dozermapper.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 125 126 127 128 129 <?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 https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context https://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="excludedExceptions"> <array> <value>org.springframework.web.util.NestedServletException</value> </array> </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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://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 https://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-spring https://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>