doma2によるデータの抽出を試す
この前は自動生成しかしていないので
自動生成なしで準備して見る
ライブラリ
doma2
mysql
プロジェクト構成
. ├── bin │ ├── META-INF │ │ └── com │ │ └── example │ │ └── dao │ │ └── ItemDao │ │ └── findAll.sql │ ├── com │ │ └── example │ │ ├── Sample01$1.class │ │ ├── Sample01.class │ │ ├── config │ │ │ └── AppConfig.class │ │ ├── dao │ │ │ ├── ItemDao.class │ │ │ └── ItemDaoImpl.class │ │ └── entity │ │ ├── Item.class │ │ └── _Item.class │ ├── doma-2.0.1.jar │ └── mysql-connector-java-5.1.40.jar ├── lib │ ├── doma-2.0.1.jar │ └── mysql-connector-java-5.1.40.jar └── src ├── META-INF │ └── com │ └── example │ └── dao │ └── ItemDao │ └── findAll.sql └── com └── example ├── Sample01.java ├── config │ └── AppConfig.java ├── dao │ └── ItemDao.java └── entity └── Item.java
設定情報クラス
AppConfig
package com.example.config; import javax.sql.DataSource; import org.seasar.doma.SingletonConfig; import org.seasar.doma.jdbc.Config; import org.seasar.doma.jdbc.dialect.Dialect; import org.seasar.doma.jdbc.dialect.MysqlDialect; import org.seasar.doma.jdbc.tx.LocalTransactionDataSource; import org.seasar.doma.jdbc.tx.LocalTransactionManager; import org.seasar.doma.jdbc.tx.TransactionManager; @SingletonConfig public class AppConfig implements Config { private static final AppConfig INSTANCE = new AppConfig(); private final Dialect dialect; private final LocalTransactionDataSource dataSource; private final TransactionManager transactionManager; private AppConfig() { dialect = new MysqlDialect(); dataSource = new LocalTransactionDataSource("jdbc:mysql://192.168.33.10:3306/myapp?useSSL=false", "app", "Password123@"); transactionManager = new LocalTransactionManager(dataSource.getLocalTransaction(getJdbcLogger())); } @Override public DataSource getDataSource() { // TODO Auto-generated method stub return dataSource; } @Override public Dialect getDialect() { // TODO Auto-generated method stub return dialect; } @Override public TransactionManager getTransactionManager() { return transactionManager; } public static AppConfig singleton() { return INSTANCE; } }
エンティティ
Item
package com.example.entity; import java.time.LocalDateTime; import org.seasar.doma.Column; import org.seasar.doma.Entity; import org.seasar.doma.Id; import org.seasar.doma.Table; @Entity @Table(name = "item") public class Item { @Id private Integer id; @Column(name = "name") private String name; @Column(name = "price") private Integer price; @Column(name = "create_at") private LocalDateTime createAt; @Column(name = "update_at") private LocalDateTime updateAt; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public LocalDateTime getCreateAt() { return createAt; } public void setCreateAt(LocalDateTime createAt) { this.createAt = createAt; } public LocalDateTime getUpdateAt() { return updateAt; } public void setUpdateAt(LocalDateTime updateAt) { this.updateAt = updateAt; } }
Dao
ItemDao
package com.example.dao; import java.util.List; import org.seasar.doma.Dao; import org.seasar.doma.Select; import com.example.config.AppConfig; import com.example.entity.Item; @Dao(config = AppConfig.class) public interface ItemDao { @Select List<Item> findAll(); }
findAll.sql
select /*%expand*/* from item order by id asc
実行用クラス
Sample01.java
package com.example; import java.util.List; import org.seasar.doma.jdbc.tx.TransactionManager; import com.example.config.AppConfig; import com.example.dao.ItemDao; import com.example.dao.ItemDaoImpl; import com.example.entity.Item; public class Sample01 { public static void main(String[] args) { TransactionManager tm = AppConfig.singleton().getTransactionManager(); tm.required(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub ItemDao dao = new ItemDaoImpl(); List<Item> list = dao.findAll(); System.out.println(list.size()); } }); } }
↓
実行結果
12 24, 2016 1:40:25 午前 org.seasar.doma.jdbc.tx.LocalTransaction begin 情報: [DOMA2063] ローカルトランザクション[1190654826]を開始しました。 12 24, 2016 1:40:25 午前 com.example.dao.ItemDaoImpl findAll 情報: [DOMA2220] ENTER : クラス=[com.example.dao.ItemDaoImpl], メソッド=[findAll] 12 24, 2016 1:40:25 午前 com.example.dao.ItemDaoImpl findAll 情報: [DOMA2076] SQLログ : SQLファイル=[META-INF/com/example/dao/ItemDao/findAll.sql], select id, name, price, create_at, update_at from item order by id asc 12 24, 2016 1:40:25 午前 com.example.dao.ItemDaoImpl findAll 情報: [DOMA2221] EXIT : クラス=[com.example.dao.ItemDaoImpl], メソッド=[findAll] 6 12 24, 2016 1:40:25 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit 情報: [DOMA2067] ローカルトランザクション[1190654826]をコミットしました。 12 24, 2016 1:40:25 午前 org.seasar.doma.jdbc.tx.LocalTransaction commit 情報: [DOMA2064] ローカルトランザクション[1190654826]を終了しました。
動きました(^^)
ログにsqlを表示する?
参考
Doma2のgenで自動生成を行う
Doma2
ORマッパーらしい
SQLファイルとか書いてなんかできるらしいよ
今回やること
Doma2でDBを参照していい感じのエンティティとかを作成できるらしいので準備して見る。
ライブラリ
doma2
doma2-gen
freemarker
mysl
設定
プロジェクトを作成する
ライブラリを指定の場所へ配置しておく
設定ファイル編集
doma-gen-build.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="doma-gen-example" default="gen" basedir="."> <!-- javaDestDir --> <property name="javaDestDir" value="src"/> <!-- sqlDestDir --> <property name="sqlDestDir" value="src"/> <!-- dialectName --> <property name="dialectName" value="mysql"/> <!-- driverClassName --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.33.10:3306/myapp"/> <property name="user" value="app"/> <property name="password" value="Password123@"/> <!-- package --> <property name="entityPackageName" value="com.example.mshige1979.server.db.entity"/> <property name="daoPackageName" value="com.example.mshige1979.server.db.dao"/> <property name="configClassName" value="com.example.mshige1979.server.db.config.AppConfig"/> <property name="sqlTestClassName" value="com.example.mshige1979.server.db.SqlTest"/> <property name="sqlFilePattern" value="META-INF/**/*.sql"/> <path id="classpath"> <fileset dir="WEB-INF/lib" includes="*.jar"/> </path> <taskdef name="gen" classname="org.seasar.doma.extension.gen.task.Gen" classpathref="classpath" loaderref="loader"/> <typedef name="entityConfig" classname="org.seasar.doma.extension.gen.task.EntityConfig" loaderref="loader"/> <typedef name="daoConfig" classname="org.seasar.doma.extension.gen.task.DaoConfig" loaderref="loader"/> <typedef name="sqlConfig" classname="org.seasar.doma.extension.gen.task.SqlConfig" loaderref="loader"/> <target name="gen"> <gen dialectName="${dialectName}" driverClassName="${driverClassName}" url="${url}" user="${user}" password="${password}"> <entityConfig destdir="${javaDestDir}" packageName="${entityPackageName}" /> <daoConfig destdir="${javaDestDir}" packageName="${daoPackageName}" configClassName="${configClassName}" /> <sqlConfig destdir="${sqlDestDir}" /> </gen> </target> <target name="genTest"> <genTest dialectName="${dialectName}" driverClassName="${driverClassName}" url="${url}" user="${user}" password="${password}"> <sqlTestConfig destdir="${javaDestDir}" testClassName="${sqlTestClassName}"> <fileset dir="${sqlDestDir}"> <include name="${sqlFilePattern}"/> </fileset> </sqlTestConfig> </genTest> </target> </project>
実行する
↓
Buildfile: sample_spring_doma2a/doma-gen-build.xml gen: [gen] [DOMAGEN0017] 方言にはクラス[org.seasar.doma.extension.gen.dialect.MysqlGenDialect]が使用されます。 [gen] Wed Dec 21 00:17:40 JST 2016 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/com/example/mshige1979/server/db/entity/Item.java [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/META-INF/com/example/mshige1979/server/db/dao/ItemDao/selectById.sql [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/com/example/mshige1979/server/db/entity/Memo.java [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/META-INF/com/example/mshige1979/server/db/dao/MemoDao/selectById.sql [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/com/example/mshige1979/server/db/entity/ObjData.java [gen] [DOMAGEN0020] ファイルを上書きしました。/Users/matsumotoshigeharu/Documents/workspace/sample_spring_doma2a/src/META-INF/com/example/mshige1979/server/db/dao/ObjDataDao/selectById.sql BUILD SUCCESSFUL Total time: 1 second
できたもの(一部)
ItemDao.java
package com.example.mshige1979.server.db.dao; import com.example.mshige1979.server.db.config.AppConfig; import com.example.mshige1979.server.db.entity.Item; import org.seasar.doma.Dao; import org.seasar.doma.Delete; import org.seasar.doma.Insert; import org.seasar.doma.Select; import org.seasar.doma.Update; /** */ @Dao(config = AppConfig.class) public interface ItemDao { /** * @param id * @return the Item entity */ @Select Item selectById(Integer id); /** * @param entity * @return affected rows */ @Insert int insert(Item entity); /** * @param entity * @return affected rows */ @Update int update(Item entity); /** * @param entity * @return affected rows */ @Delete int delete(Item entity); }
Item.java
package com.example.mshige1979.server.db.entity; import java.time.LocalDateTime; import org.seasar.doma.Column; import org.seasar.doma.Entity; import org.seasar.doma.GeneratedValue; import org.seasar.doma.GenerationType; import org.seasar.doma.Id; import org.seasar.doma.Table; /** * */ @Entity(listener = ItemListener.class) @Table(name = "item") public class Item { /** */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") Integer id; /** */ @Column(name = "name") String name; /** */ @Column(name = "price") Integer price; /** */ @Column(name = "create_at") LocalDateTime createAt; /** */ @Column(name = "update_at") LocalDateTime updateAt; /** * Returns the id. * * @return the id */ public Integer getId() { return id; } /** * Sets the id. * * @param id the id */ public void setId(Integer id) { this.id = id; } /** * Returns the name. * * @return the name */ public String getName() { return name; } /** * Sets the name. * * @param name the name */ public void setName(String name) { this.name = name; } /** * Returns the price. * * @return the price */ public Integer getPrice() { return price; } /** * Sets the price. * * @param price the price */ public void setPrice(Integer price) { this.price = price; } /** * Returns the createAt. * * @return the createAt */ public LocalDateTime getCreateAt() { return createAt; } /** * Sets the createAt. * * @param createAt the createAt */ public void setCreateAt(LocalDateTime createAt) { this.createAt = createAt; } /** * Returns the updateAt. * * @return the updateAt */ public LocalDateTime getUpdateAt() { return updateAt; } /** * Sets the updateAt. * * @param updateAt the updateAt */ public void setUpdateAt(LocalDateTime updateAt) { this.updateAt = updateAt; } }
JavaからDLLを呼び出してみる3
タイトルあんまり名前が繋がってない
まあ、意味は伝わるはず
C++のクラス用DLLを作成
MathFuncsDll.h
// MathFuncsDll.h #ifdef MATHFUNCSDLL_EXPORTS #define MATHFUNCSDLL_API __declspec(dllexport) #else #define MATHFUNCSDLL_API __declspec(dllimport) #endif namespace MathFuncs { // This class is exported from the MathFuncsDll.dll class MyMathFuncs { public: // Returns a + b static MATHFUNCSDLL_API double Add(double a, double b); // Returns a - b static MATHFUNCSDLL_API double Subtract(double a, double b); // Returns a * b static MATHFUNCSDLL_API double Multiply(double a, double b); // Returns a / b // Throws const std::invalid_argument& if b is 0 static MATHFUNCSDLL_API double Divide(double a, double b); }; }
MathFuncsDll.cpp
// MathFuncsDll.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include "MathFuncsDll.h" #include <stdexcept> using namespace std; namespace MathFuncs { double MyMathFuncs::Add(double a, double b) { return a + b; } double MyMathFuncs::Subtract(double a, double b) { return a - b; } double MyMathFuncs::Multiply(double a, double b) { return a * b; } double MyMathFuncs::Divide(double a, double b) { if (b == 0) { throw invalid_argument("b cannot be zero!"); } return a / b; } }
ラッパー用
SampleDllWrapper.cpp
// SampleDllWrapper.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。 // #include "stdafx.h" #include "./MathFuncsDll.h" double MyMathFuncs_Add(double a, double b) { return MathFuncs::MyMathFuncs::Add(a, b); }
SampleDllWrapper.def
LIBRARY SampleDllWrapper EXPORTS MyMathFuncs_Add @1
※DLLを参照して、ヘッダーファイルを指定する
Java
Sample02.java
package sample02; import com.sun.jna.Library; import com.sun.jna.Native; interface HelloLib extends Library { HelloLib INSTANCE = (HelloLib) Native.loadLibrary("SampleDllWrapper.dll", HelloLib.class); // Cの関数名と一致させる double MyMathFuncs_Add(double s1, double s2); } public class Sample02 { public static void main(String[] args) { HelloLib hello = HelloLib.INSTANCE; double a = 100; double b = 1200; System.out.println(hello.MyMathFuncs_Add(a, b)); } }
↓
1300.0
※データ型がうまくあわないとエラーになりました(´・ω・`)
わかったこと
DLLを静的に読み込んでいるのでヘッダーファイルなどが必要。
最終的にはDLLだけでやりたいのでヘッダーファイルなしのバージョンも知りたい
難しいなあ(´・ω・`)
Windowsで作成したDLLをJavaで動かす2
関数を1つしか定義していなかったので
複数定義した場合のパターンをやってみる
SampleDll.cpp
// SampleDll.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。 // #include "stdafx.h" #include "stdio.h" int GetHello(int data) { printf("%d", data); return 0; } int GetHelloString(char *data) { printf("%s", data); return 0; } int GetHelloAdd(int data1, int data2) { return data1 + data2; }
SampleDll.def
LIBRARY SampleDll EXPORTS GetHello @1 GetHelloString @2 GetHelloAdd @3
※この@1とかって引数のやつと思ったけど違うようです。
DEF ファイルを使った DLL からのエクスポート
エクスポート関数を確認
Dump of file SampleDll.dll File Type: DLL Section contains the following exports for SampleDll.dll 00000000 characteristics 5857D09C time date stamp Mon Dec 19 21:20:44 2016 0.00 version 1 ordinal base 3 number of functions 3 number of names ordinal hint RVA name 1 0 0001102D GetHello = @ILT+40(?GetHello@@YAHH@Z) 3 1 00011190 GetHelloAdd = @ILT+395(?GetHelloAdd@@YAHHH@Z) 2 2 0001121C GetHelloString = @ILT+535(?GetHelloString@@YAHPEAD@Z) Summary 1000 .00cfg 1000 .data 1000 .gfids 1000 .idata 3000 .pdata 3000 .rdata 1000 .reloc 1000 .rsrc 8000 .text 10000 .textbss
Javaで実装
Sample01.java
package sample01; import com.sun.jna.Library; import com.sun.jna.Native; interface HelloLib extends Library { HelloLib INSTANCE = (HelloLib) Native.loadLibrary("SampleDll.dll", HelloLib.class); // Cの関数名と一致させる int GetHello(int s); int GetHelloString(String s); int GetHelloAdd(int s1, int s2); } public class Sample01 { public static void main(String[] args) { HelloLib hello = HelloLib.INSTANCE; hello.GetHello(100); hello.GetHelloString("hoge"); System.out.println(hello.GetHelloAdd(600, 1200)); } }
↓
1800 100hoge
※system.out.printlnのほうが先に出力していますね、なんで?
わかったこと
・char *で定義したら Stringで一致する。
・byte[]のやつは一部文字化けらしき問題を起こすらしい
・結果の出力は前後する場合がある
Spring Bootでアップロードファイルを受け取る
FormとかBeanとかいうクラスを使用することで受け取ることが可能になりました。
ファイルってどうするのかな?
MultipartFileとかいうクラス
があれば受け取れます(^^)
フォーム系
SendDataForm.java
package com.example.form; import java.io.Serializable; import org.springframework.web.multipart.MultipartFile; public class SendDataForm implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String id; private String text; private String item_id; private MultipartFile upload_file; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getItem_id() { return item_id; } public void setItem_id(String item_id) { this.item_id = item_id; } public MultipartFile getUpload_file() { return upload_file; } public void setUpload_file(MultipartFile upload_file) { this.upload_file = upload_file; } public String toString(){ String str = ""; str += "id = " + this.id + "\n"; str += "text = " + this.text + "\n"; str += "item_id = " + this.item_id + "\n"; if(null != this.upload_file){ str += "upload_file = " + this.upload_file.getOriginalFilename() + " size = " + this.upload_file.getSize() + "\n"; } return str; } }
Item.java
package com.example.form; import java.io.Serializable; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Item implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String id; private String text; private String item_id; private String upload_file; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getItem_id() { return item_id; } public void setItem_id(String item_id) { this.item_id = item_id; } public String getUpload_file() { return upload_file; } public void setUpload_file(String upload_file) { this.upload_file = upload_file; } }
受信用コントローラー
SampleController.java
package com.example.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.example.form.Item; import com.example.form.SendDataForm; @RestController @RequestMapping("/sample") public class SampleController { @RequestMapping(value = "/upload", method = {RequestMethod.POST}) public Item upload(SendDataForm form){ Item item = new Item(); item.setId(form.getId()); item.setText(form.getText()); item.setItem_id(form.getItem_id()); item.setUpload_file(form.getUpload_file().getOriginalFilename()); return item; } }
実験
$ curl -X POST http://localhost:8080/sample/upload \ > -F "id=100" \ > -F "text=hogehoge" \ > -F "item_id=12345678" \ > -F "upload_file=@work/file/image.jpg" {"id":"100","text":"hogehoge","item_id":"12345678","upload_file":"image.jpg"}
※curlってこういうとき簡単に試せるから便利(^^)
MultipartFileの中でファイルの名前やサイズ、データも管理できるみたいなので結構便利な感じ
フォームで送信する形式になるのでヘッダーにjsonとかは設定できないんですね…なんかその辺まだ良くわかっていない(´・ω・`)
まあ、json形式で返却できるみたいなので大丈夫かな?
Spring Bootでjson文字列を受信してクラスに割り当てる
BeanとかFormとか呼ばれているもので画面とかの項目が設定されるやつ
前の時代などではパラメータを指定して取り込んでいたけどjsonで送った場合なども対応したクラスに割り当てたい場合等に対応
json形式で送った際きちんとクラスに設定されるか検証する
やること
受付用のクラスを作成
@RequestBodyアノテーションを使用
@RequestMappingで受け付けるデータを指定
受付用クラス
ItemForm.java
package com.example.form; import java.io.Serializable; public class ItemForm implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name; private String date; private String price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String toString(){ return "name = " + this.name + " date = " + this.date + " price = " + this.price; } }
ItemsForm.java
package com.example.form; import java.io.Serializable; import java.util.List; public class ItemsForm implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String count; private List<ItemForm> items; public String getCount() { return count; } public void setCount(String count) { this.count = count; } public List<ItemForm> getItems() { return items; } public void setItems(List<ItemForm> items) { this.items = items; } public String toString(){ String str = ""; str = "count = " + this.count + "\n"; str += ""; for(ItemForm item : this.items) { str += item.toString() + "\n"; } return str; } }
コントローラー設定
SampleController.java
package com.example.web; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.example.form.ItemForm; import com.example.form.ItemsForm; @RestController @RequestMapping("/sample") public class SampleController { @RequestMapping(value = "/test1", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public String item(@RequestBody ItemForm form){ return form.toString(); } @RequestMapping(value = "/test2", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public String items(@RequestBody ItemsForm form){ return form.toString(); } }
実行結果
・/sample/test1
$ curl -X POST \ > -H 'Content-Type:application/json' \ > -d '{ > "name": "hogehoge", > "date": "20151028", > "price": "12000" > }' http://localhost:8080/sample/test1 name = hogehoge date = 20151028 price = 12000
・/sample/test2
$ curl -X POST \ > -H 'Content-Type:application/json' \ > -d '{ > "count": "10", > "items": [ > { > "name": "foo1", > "date": "20160112", > "price": "1200" > }, > { > "name": "foo2", > "date": "20160212", > "price": "4300" > }, > { > "name": "foo3", > "date": "20160217", > "price": "2500" > }, > { > "name": "foo4", > "date": "20160519", > "price": "2000" > }, > { > "name": "foo5", > "date": "20160630", > "price": "1500" > } > ] > }' http://localhost:8080/sample/test2 count = 10 name = foo1 date = 20160112 price = 1200 name = foo2 date = 20160212 price = 4300 name = foo3 date = 20160217 price = 2500 name = foo4 date = 20160519 price = 2000 name = foo5 date = 20160630 price = 1500 $
クラスを階層構造を内部に持つことでネスト構造の場合も対応できる感じ
ファイルとかできるかはわからない
送り込むjsonのキーが存在しなくてもクラスの方はnullになるだけでエラーを起こすわけではない
Spring BootでXMLやJSONを返す
忙しいです…
Spring BootでRest APIを作成する場合には
・コントローラー用のクラスに"@RestController"アノテーションを付ける
・クラスを任意で用意して返却することで基本、json形式で返却できる
・XMLを返したい場合は返却用のクラスに"@XmlRootElement"を付与する必要があります
返却用のクラス
Item.java
package com.example.entity; import java.io.Serializable; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Item implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name; private String date; public Item(){ } public Item(String name, String date){ this.name = name; this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } }
コントローラー
Sample1Controller.java
package com.example.web; import java.util.List; import java.util.ArrayList; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.example.entity.Item; @RestController @RequestMapping("/sample1") public class Sample1Controller { private List<Item> items = new ArrayList<Item>(); Sample1Controller(){ items.add(new Item("hoeg1", "20131122")); items.add(new Item("hoeg2", "20131130")); items.add(new Item("hoeg3", "20131205")); items.add(new Item("hoeg4", "20131210")); items.add(new Item("hoeg5", "20131225")); items.add(new Item("hoeg6", "20141012")); items.add(new Item("hoeg7", "20141014")); items.add(new Item("hoeg8", "20141024")); } @RequestMapping(value = "/", method = { RequestMethod.GET }) public String index(){ return "/sample/index"; } @RequestMapping(value = "/test1", method = { RequestMethod.GET }) public String test1(){ return "/sample/test1"; } @RequestMapping(value = "/items", method = { RequestMethod.GET }) public List<Item> items(){ return this.items; } @RequestMapping(value = "/item/{id}", method = { RequestMethod.GET }) public Item item(@PathVariable int id){ return this.items.get(id); } }
内容
・/sample1
→ "/sample/index"を返す
$ curl -i -H "Accept: application/json" \ > http://localhost:8080/sample1/ HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Content-Length: 13 Date: Sat, 17 Dec 2016 04:10:47 GMT /sample/index
・/sample1/test1
→ "/sample/test1"を返す
$ curl -i -H "Accept: application/json" \ > http://localhost:8080/sample1/test1 HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Content-Length: 13 Date: Sat, 17 Dec 2016 04:11:29 GMT /sample/test1
・/sample1/items
→ itemクラスのjson一覧を返す
$ curl -i -H "Accept: application/json" \ > http://localhost:8080/sample1/items HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Sat, 17 Dec 2016 04:11:56 GMT [{"name":"hoeg1","date":"20131122"},{"name":"hoeg2","date":"20131130"},{"name":"hoeg3","date":"20131205"},{"name":"hoeg4","date":"20131210"},{"name":"hoeg5","date":"20131225"},{"name":"hoeg6","date":"20141012"},{"name":"hoeg7","date":"20141014"},{"name":"hoeg8","date":"20141024"}]
・/sample1/item{id}
→ itemクラスのjsonを返す
$ curl -i -H "Accept: application/json" \ > http://localhost:8080/sample1/item/5 HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Sat, 17 Dec 2016 04:12:21 GMT {"name":"hoeg6","date":"20141012"}