InitDatabase の実行まで:REST(4)
- JsonConverter の作成
Json encode/decode のためのクラス。ContextResolver を implement して作る。これを登録すると,このクラスの Jackson ObjectMapper が使用されるようになる。 Lazy fetch を追いかけないために Hibernate4Module を登録している。
hbm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false); hbm.configure(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION, false); mapper.registerModule(hbm);
これをサーバ側では web.xml に加える。<context-param> <param-name>resteasy.providers</param-name> <param-value>open.dolphin.JsonConverter</param-value> </context-param>
クライアント側では ResteasyClient に登録する。ResteasyClient client = new ResteasyClientBuilder().build(); client.register(new JsonConverter());
- open.dolphin.infomodel に以下のファイルをコピー
- InfoModel
- IInfoModel
- UserModel
- UserLiteModel
- LicenseModel
- DepartmentModel
- FacilityModel
- RoleModel
- RadiologyMethodValue
- bi-directional reference の解消
UserModel と RoleModel はお互いにお互いのフィールドを参照しているため,そのままだと json 化の時に無限ループに入ってしまって Stack Overflow となる。対策には色々あるようだが,一番簡単そうな @JsonIdentityInfo を使う方法を使った。@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class) public class UserModel extends InfoModel { :
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class) public class RoleModel extends InfoModel { :
これで UserModel を json 化すると,以下のように UserModel の roles 内に出てくる UserModel が,親の UUID "f0c88e43-23bd-4aa4-8a71-e42ab6b2e257" への参照としてシリアライズされる。{ "@id" : "f0c88e43-23bd-4aa4-8a71-e42ab6b2e257", "id" : 0, "roles" : [ { "@id" : "e0c1c1ce-06a1-45da-8795-afb59bb71ccf", "id" : 0, "user" : "f0c88e43-23bd-4aa4-8a71-e42ab6b2e257" } ] }
- RemoteSystemService, RemoteSystemServiceImpl の改変
RMI では @Remote を使っていたが,REST では @Path と @GET/@PUT/@POST/@DELETE を使う。また,json を使うために @Pruduces と @Consumes を付ける。これらを置き換えた SystemService と SystemServiceImpl を作る。GET/PUT/POST の使い分けが難しいが,引数が1個の場合はとりあえず POST にしておけば,message body にパラメータを埋め込んでくれる。(引数が複数の場合は,@PathParam など,URL にパラメータを埋め込む必要がある) - クライアントからのアクセス方法
以下のような手順で remote の Service クラスが取れる。ここらへんの手続きを DolphinClientContext というクラスにまとめた。// Resteasy ResteasyClient client = new ResteasyClientBuilder().connectionPoolSize(20).build(); // register providers try { AuthorizationFilter authorizationFilter = new AuthorizationFilter(userId, hashPass); JsonConverter jsonConverter = new JsonConverter(); client.register(authorizationFilter); client.register(jsonConverter); } catch (Exception e) { e.printStackTrace(System.err); } String restUrl = String.format(("http://%s/%s"), hostAddress, DOLPHIN_PATH); ResteasyWebTarget target = client.target(restUrl); SystemService service = target.proxy(SystemService.class);
connectionPoolSize を設定しないと pool を使い果たした時点で以下のようなエラーとなるjavax.ws.rs.ProcessingException: Unable to invoke request Caused by: java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.
- NetBeans でちょっと混乱したところ
server を「ビルド」すると war と -classes jar ファイルができて client に反映される。しかし「ビルド」は deploy には影響しない。server を「実行」すると現在の class がデプロイされる。server のファイルを編集して保存するとすぐ deploy されるが,この時 -classes.jar ファイルはできていないので client はその編集を知らない。client に反映させるためには「ビルド」が必要になる。
« 依存性:REST(3) | トップページ | infomodel,ejb,dto の引っ越し:REST(5) »
「OpenDolphin」カテゴリの記事
- Java 17 への移行(7) - OpenDolphin client の対応 (2023.02.04)
- Java 17 への移行(6) - Hibernate 6 でやらかす(2023.02.03)
- Java 17 への移行(5) - OpenDolphin server の対応(2023.02.02)
- Java 17 への移行(4) - OpenSearch の準備 [ubuntu 編](2023.02.01)
- Java 17 への移行(3) - OpenSearch の準備 [mac 編](2023.01.31)