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

## 環境
- Eclipse Photon (4.8)
- Java 8
- Wicket 7.10
- Tomcat 8
- jackson 2.9.2
- jsencrypt

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

## RSA暗号化用 [jsencrypt](https://github.com/travist/jsencrypt) でリクエスト

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

```js:myjsencrypt.js
my.jsencrypt = {
        pubKey: '-----BEGIN PUBLIC KEY-----\
公開鍵内容
-----END PUBLIC KEY-----\
'
```
初期化します。

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

リクエストを投げます。

```js: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](https://github.com/FasterXML/jackson) が良さそうでしたので使ってみました。
実際簡単に使えます。導入は pom.xml に設定するだけ。

```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 暗号化・復号化](https://qiita.com/a__i__r/items/6abef31f3ca2c1cfa54c) を参考にしてください。

```java: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設定用のメソッドを用意。

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

結果用のJSONを返します。

```java: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 は見やすいので入れてます。

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