Spring3 + MyBatis + RESTEasy
Spring3とMyBatisとRESTEasy を使って開発・・・ のメモ開発環境:Windows7、Eclipse3.7+m2eプラグイン、Maven Integration for Eclipse WTP※もしかすると、既に入れていたプラグインのおかげがあるかも参考SpringとMyBatisを使ったアプリケーション開発のメモ -その1-SpringとMyBatisを使ったアプリケーション開発のメモ -その2-この二つを使って、Spring3+MyBatisのサンプルプログラムを作ったので、次は、SpringとMyBatisを使ったアプリケーション開発のメモ -その3 RESTEasy編-SpringとMyBatisを使ったアプリケーション開発のメモ -その4 RESTEasy編-JAX-RSでHTTPリクエストを高度に扱うを参考にやってみる。■Maven依存関係の追加 ( pom.xml の編集 と同等)プロジェクトを選択し、右クリック→Maven→依存関係の追加 にて下記のライブラリを追加する・spring-core 3.1.0・spring-tx 3.1.0・spring-web 3.1.0・mybatis 3.0.6・mybatis-spring 1.0.2・mysql-connector-java 5.1.18・resteasy-jaxrs 2.3.1 GA・resteasy-spring 2.3.1.GA・servlet-api javax.servlet 2.5 provided※ scope provided について 3. Maven 入門 (2) 3.1.1. 依存性の指定とスコープ------------ 引用 ----------------------「provided」は servlet-api.jar のような実行環境で提供されるライブラリに対して指定します。----------------------------------------まずこれを追加した。■web.xmlの編集/maven_spring_rest_test/src/main/webapp/WEB-INF/web.xmlにweb.xmlがあるので、その3 を参考に、追記。※アメブロは、<pre>タグがうまく使えねぇ・・・・キイーーーーーーーー■起動して、テストhttp://localhost:8080/maven_spring_rest_test/rest/card/これは、ブラウザで見ると GET Methodでたたかれるので、int getNumOfCards();の結果が出る。/maven_spring_rest_test/src/main/java/jp/ameba/cs/springmybatis/jaxrs/CardRestServiceImpl.javaにブレイクポイントを設定。サーバをDEBUGモードで起動すると・・・・ちゃんとブレイクポイントでとまってる~♪これで、開発&デバッグはOKですね。次に、spring-setting.xml というのを使っていましたが、こちらをデフォルトの applicationContext.xmlに変更web.xmlから spring-setting.xml の記述を削除spring-setting.xml を applicationContext.xml にリネームして、/maven_spring_rest_test/src/main/webapp/WEB-INF 直下に。わざわざ、spring-setting.xmlというデフォルト以外にする必要はないですからね。■applicationContext.xmlからサービスクラスのBean定義をアノテーションベースに変更applicationContext.xmlに、<!-- サービスクラスの定義 --><bean id="cardService" class="jp.ameba.cs.springmybatis.service.CardServiceImpl" /><!-- RESTfulサービスクラスの定義 --><bean id="cardRestService" class="jp.ameba.cs.springmybatis.jaxrs.CardRestServiceImpl" />といった記述がありましたが、せっかくアノテーションを使えるので、そちらの記載に変更。・上記のサービスクラスの定義を削除・アノテーションベースを applicationContext.xmlに設定<context:annotation-config /><context:component-scan base-package="jp.ameba.cs" />と<beans default-autowire="byName" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd ">contextを有効にするために、xmlns:context="http://www.springframework.org/schema/context"とhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsdを追加してます。また、default-autowire="byName" ともしてます。autowiredを使いたいですし。・/maven_spring_rest_test/src/main/java/jp/ameba/cs/springmybatis/jaxrs/CardRestServiceImpl.java に @Service のアノテーション追加 @Autowired private CardService cardService; とアノテーションでインジェクション・/maven_spring_rest_test/src/main/java/jp/ameba/cs/springmybatis/service/CardServiceImpl.java に @Service のアノテーション追加 @Autowired private CardMapper cardMapper; とアノテーションでインジェクション行けた♪■RESTのテストツールが欲しいRestfuse 1.0.0 - REST/HTTPの統合テストを容易にするライブラリIntroducing restfuse – a JUnit Extension to test REST APIsどうもこんなのがあるらしい。ちょっと使ってみよう。Restfuseは、-------------------------- 引用 ------------------------------EclipseSource は、REST/HTTPサービスのテストを自動化するJUnit 拡張の最初の安定バージョンをオープンソースでリリースした。Restfuse はJUnitのアノテーションセットであり、個別の HttpJUnitRunner と一緒に、HTTPコールのレスポンスへのアサーションを提供する。同期と非同期の両方のリモートコールがサポートされている。Restfuseは既に Maven Centralにあるので、それを使うのに特別なリポジトリは不要である。--------------------------------------------------------------とある。なので、Mavenで取り込んでよさそう。( scope は test でやるのかな?)scope : test で追加してみた。 <dependency> <groupId>com.restfuse</groupId> <artifactId>com.eclipsesource.restfuse</artifactId> <version>1.0.0</version> <scope>test</scope> </dependency>@RunWith アノテーションがない・・・・・これは、 maven-archetype-webapp で取り込んでるJunitが 3.8.1 だったから。junit junit 4.10 に更新。@RunWith が使えるようになる。----------------------------------------------------------------------package jp.gak_timport org.junit.Rule;import org.junit.runner.RunWith;import com.eclipsesource.restfuse.Assert;import com.eclipsesource.restfuse.Destination;import com.eclipsesource.restfuse.HttpJUnitRunner;import com.eclipsesource.restfuse.Method;import com.eclipsesource.restfuse.Response;import com.eclipsesource.restfuse.annotation.Context;import com.eclipsesource.restfuse.annotation.HttpTest;@RunWith( HttpJUnitRunner.class )public class RestfuseTest { @Rule public Destination destination = new Destination( "http://localhost:8080/maven_spring_rest_test/rest/" ); @Context private Response response; // will be injected after every request @HttpTest( method = Method.GET, path = "/card" ) public void checkRestfuseOnlineStatus() { Assert.assertOk( response ); }}----------------------------------------------------------------------ためしに、webアプリを落として、実行すると、 SocketTimeoutException/card を /cards にして、実行するとjava.lang.AssertionError: expected:<200> but was:<404>(以下略)とでました。とここで、ロギングのライブラリを入れていないことに気が付いた。commons-logging と log4j をつかっていたが・・・・・・slf4j + logback にすることにする。ただ、commons-httpclient で、おまじないしないとだめっぽい。→ おまじないを入れたけどダメだったMavenで logback-classicを入れたそうすると・logback-classic-1.0.0.jar・logback-core-1.0.0.jar・slf4j-api-1..6.4.jarが入った。jcl-over-slf4j も入れておく(念のため?)logbackについて参考→Java好き、Log4J徹底解説 使い方(logback)import org.slf4j.Logger;import org.slf4j.LoggerFactory;private static Logger log = LoggerFactory.getLogger(RestfuseTest.class);として、 @HttpTest( method = Method.GET, path = "/card" ) public void checkRestfuseOnlineStatus() { Assert.assertOk( response ); String answerBody = response.getBody(String.class); log.info("answer = " + answerBody); }としたら、22:29:12 [main] INFO jp.ameba.cs.RestfuseTest - answer = 83とでた。logback.xml は、クラスパスのあるところに通した。(とりあえず、/maven_spring_rest_test/src/main/java/logback.xml )内容は、めっちゃくちゃ簡単で、<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <Target>System.out</Target> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern> </layout> </appender> <logger name="jp.or.nurs.sug"> <level value="DEBUG" /> </logger> <root> <level value="INFO" /> <appender-ref ref="STDOUT" /> </root></configuration>としました。【JSON形式で返す場合】「resteasy-jettison-provider」をMavenでインストールして、@Consumes("application/json")@Produces("application/json")とやったらできた---------------------------------------------------------------------------------------import javax.ws.rs.Consumes;import javax.ws.rs.DELETE;import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.PUT;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;@Path("/json/card")@Consumes("application/xml")@Produces("application/json")public interface CardRestJSONService { @GET @Path("/{id}") Card getCard(@PathParam("id") String id); @POST @Path("/") Card createCard(); @PUT @Path("/{id}") void updateCard(@PathParam("id") String id, Card card); @DELETE @Path("/{id}") void deleteCard(@PathParam("id") String id); @GET @Path("/") @Produces("text/plain") int getNumOfCards(); @POST @Path("/twocards/") void createTwoCards();}