Java
Wicket
JSON
Tomcat
Jackson

wicket で RSA暗号化対応 JSON API を作る

環境

  • Eclipse Photon (4.8)
  • Java 8
  • Wicket 7.10
  • Tomcat 8
  • jackson 2.9.2
  • jsencrypt

背景

wicket のページで JSON を使ってやり取りがしたい!
ついでに暗号化されたリクエストで・・・。

RSA暗号化用 jsencrypt でリクエスト

公開鍵を pubKey にセットします。

myjsencrypt.js
my.jsencrypt = {
        pubKey: '-----BEGIN PUBLIC KEY-----\
公開鍵内容
-----END PUBLIC KEY-----\
'

初期化します。

myjsencrypt.js
        // encryption setting
        var encrypt = new JSEncrypt();
        encrypt.setPublicKey(my.jsencrypt.pubKey);

リクエストを投げます。

myjsencrypt.js
        // request
        var xhr = new XMLHttpRequest();
        xhr.open("POST", 宛先URL, true);
        xhr.setRequestHeader("content-type", "application/json");
        xhr.send( encrypt.encrypt(JSON.stringify(data)) );

json 用ライブラリ

色々あるようですが、jackson が良さそうでしたので使ってみました。
実際簡単に使えます。導入は pom.xml に設定するだけ。

pom.xml
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.2</version>
        </dependency>

Wicket での ページ処理

リクエストを取得してパラメータにします。
RSAUtil は java 8 での RSA 暗号化・復号化 を参考にしてください。

MyJsonPage.java
        RequestCycle requestCycle = getRequestCycle();
        final WebRequest webRequest = (WebRequest) getRequest();
        final HttpServletRequest rawRequest = (HttpServletRequest) webRequest.getContainerRequest();

        BufferedReader br = null;
        JsonFactory jsonFactory = new JsonFactory();
        ObjectMapper jsonMapper = new ObjectMapper(jsonFactory);

        // <パラメータ名,値> の Map にする
        TypeReference<ConcurrentHashMap<String,String>> typeRef = new TypeReference<ConcurrentHashMap<String,String>>(){};

        try {
            StringBuffer sb = new StringBuffer();
            br = rawRequest.getReader();

            for (String line = br.readLine(); line != null; line = br.readLine()) {
                sb.append(line);
            }

            // decrypt RSA input
            PrivateKey privKey = RSAUtil.readPrvateKeyFromPem(秘密鍵のファイル);
            String decrypted = RSAUtil.decryptWithPrivateKey(sb.toString(), privKey);

            // decrypted params to json map
            inputJsonMap = jsonMapper.readValue(decrypted, typeRef);

        } catch (Exception e) {
            /* エラー処理 */
        }

パラメータが取得できたので、このページでの処理をして・・・

Content-Type設定用のメソッドを用意。

MyJsonPage.java
    // Set content-type
    protected String getContentType() {
        final String encoding = getApplication().getRequestCycleSettings().getResponseRequestEncoding();
        return "application/json; charset=" + encoding;
    }

結果用のJSONを返します。

MyJsonPage.java
        // build JSON response
        try {
            jsonResponse = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(returnObject);
        } catch (JsonProcessingException e) {
            /* エラー処理 */
        }

        requestCycle.scheduleRequestHandlerAfterCurrent(
                new ResourceStreamRequestHandler(
                    new StringResourceStream(jsonResponse)  ) {

                    @Override
                    public void respond(IRequestCycle requestCycle) {
                        ((WebResponse) requestCycle.getResponse()).setContentType(getContentType());
                        super.respond(requestCycle);
                    }
                }
                );

Objectから JSON へ変換してくれるので便利ですね。
PrettyPrinter は見やすいので入れてます。

以上です。お疲れ様でした!