Spring Frameworkの”org.springframework.web.util”パッケージの便利なクラス

# 概要

Spring Frameworkの”org.springframework.web.util”パッケージにあるユーティリティークラスを調べた時のメモです。

**環境**

* Windows10 Professional
* Java 1.8.0_101
* Spring Boot 1.4.1
  * Spring Framework 4.3.3

**参考**

* [Package org.springframework.web.util] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/package-summary.html)


# Package

org.springframework.web.util

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/package-summary.html)
* [github] (https://github.com/spring-projects/spring-framework/tree/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util)


## Class

### HtmlUtils

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/HtmlUtils.html)
* [github] (https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util/HtmlUtils.java)
* [HTML Document Representation] (https://www.w3.org/TR/html4/charset.html)

HTMLをエスケープ・アンエスケープするためのユーティリティークラス。


#### htmlEscape

Special Charactersを文字実体参照にエスケープする。

```java
String str = "<div class=\"container-fluid\"><div class=\"row\"><div class=\"col-md-12 well\"><h2>タイトル</h2></div></div></div>";
String esc = HtmlUtils.htmlEscape(str);
System.out.println(esc);
// → &lt;div class=&quot;container-fluid&quot;&gt;&lt;div class=&quot;row&quot;&gt;&lt;div class=&quot;col-md-12 well&quot;&gt;&lt;h2&gt;タイトル&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
```

#### htmlEscapeDecimal

Special Charactersを10進数の数値文字参照にエスケープする。

```java
String str = "<div class=\"container-fluid\"><div class=\"row\"><div class=\"col-md-12 well\"><h2>タイトル</h2></div></div></div>";
String esc = HtmlUtils.htmlEscapeDecimal(str);
System.out.println(esc);
// → &#60;div class=&#34;container-fluid&#34;&#62;&#60;div class=&#34;row&#34;&#62;&#60;div class=&#34;col-md-12 well&#34;&#62;&#60;h2&#62;タイトル&#60;/h2&#62;&#60;/div&#62;&#60;/div&#62;&#60;/div&#62;
```

#### htmlEscapeHex

Special Charactersを16進数の数値文字参照にエスケープする。

```java
String str = "<div class=\"container-fluid\"><div class=\"row\"><div class=\"col-md-12 well\"><h2>タイトル</h2></div></div></div>";
String esc = HtmlUtils.htmlEscapeHex(str);
System.out.println(esc);
// → &#x3c;div class=&#x22;container-fluid&#x22;&#x3e;&#x3c;div class=&#x22;row&#x22;&#x3e;&#x3c;div class=&#x22;col-md-12 well&#x22;&#x3e;&#x3c;h2&#x3e;タイトル&#x3c;/h2&#x3e;&#x3c;/div&#x3e;&#x3c;/div&#x3e;&#x3c;/div&#x3e;
```

#### htmlUnescape

エスケープされた文字列を平文へ戻す。

```java
String uesc = HtmlUtils.htmlUnescape("&lt;div class=&quot;container-fluid&quot;&gt;&lt;div class=&quot;row&quot;&gt;&lt;div class=&quot;col-md-12 well&quot;&gt;&lt;h2&gt;タイトル&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;");
System.out.println(uesc);
// → <div class="container-fluid"><div class="row"><div class="col-md-12 well"><h2>タイトル</h2></div></div></div>

uesc = HtmlUtils.htmlUnescape("&#60;div class=&#34;container-fluid&#34;&#62;&#60;div class=&#34;row&#34;&#62;&#60;div class=&#34;col-md-12 well&#34;&#62;&#60;h2&#62;タイトル&#60;/h2&#62;&#60;/div&#62;&#60;/div&#62;&#60;/div&#62;");
System.out.println(uesc);
// → <div class="container-fluid"><div class="row"><div class="col-md-12 well"><h2>タイトル</h2></div></div></div>

uesc = HtmlUtils.htmlUnescape("&#x3c;div class=&#x22;container-fluid&#x22;&#x3e;&#x3c;div class=&#x22;row&#x22;&#x3e;&#x3c;div class=&#x22;col-md-12 well&#x22;&#x3e;&#x3c;h2&#x3e;タイトル&#x3c;/h2&#x3e;&#x3c;/div&#x3e;&#x3c;/div&#x3e;&#x3c;/div&#x3e;");
System.out.println(uesc);
// → <div class="container-fluid"><div class="row"><div class="col-md-12 well"><h2>タイトル</h2></div></div></div>
```


### JavaScriptUtils

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/JavaScriptUtils.html)
* [github] (https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util/JavaScriptUtils.java)
* [MDN > Web technology For developers > JavaScript > JavaScript Guide > Grammar and types] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types)

JavaScriptをエスケープするためのユーティリティクラス。

#### javaScriptEscape

JavascriptのSpecial Charactersをエスケープする。

```java
String script = "<script type=\"text/javascript\">alert(document.cookie);</script>";
String esc = JavaScriptUtils.javaScriptEscape(script);
System.out.println(esc);
// → \u003Cscript type=\"text\/javascript\"\u003Ealert(document.cookie);\u003C\/script\u003E
```


### UriUtils

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/UriUtils.html)
* [github] (https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util/UriUtils.java)
* [RFC3986] (http://www.ietf.org/rfc/rfc3986.txt)

URIのエンコードおよびデコードするためのユーティリティクラス。(RFC3986ベース)

URI

```html
http://user:password@www.example.com:9000/contents/detail?qid=1&kw=battery#section7
```

|part      |example              |
|:---------|:--------------------|
|scheme    | `http:`             |
|authority | `//user:password@www.example.com:9000` |
|userinfo  | `user:password`     |
|host      | `www.example.com`   |
|port      | `:9000`             |
|path      | `/contents/detail`  |
|query     | `?qid=1&kw=battery` |
|fragment  | `#section7`         |


#### encode

URIをエンコードする。

```java
String uri = "http://user:password@www.example.com:9000/contents/detail.html?qid=1&kw=battery#section7";
String enc = UriUtils.encode(uri, StandardCharsets.UTF_8.name());
System.out.println(enc);
// → http%3A%2F%2Fuser%3Apassword%40www.example.com%3A9000%2Fcontents%2Fdetail.html%3Fqid%3D1%26kw%3Dbattery%23section7
```


#### decode

エンコードされたURIをデコードする。

```java
String uri = "http%3A%2F%2Fuser%3Apassword%40www.example.com%3A9000%2Fcontents%2Fdetail.html%3Fqid%3D1%26kw%3Dbattery%23section7";
String dec = UriUtils.decode(uri, StandardCharsets.UTF_8.name());
System.out.println(dec);
// → http://user:password@www.example.com:9000/contents/detail.html?qid=1&kw=battery#section7
```


#### extractFileExtension

URIからファイルの拡張子を取得する。

```java
String uri = "http://user:password@www.example.com:9000/contents/detail.html?qid=1&kw=battery#section7";
String extension = UriUtils.extractFileExtension(uri);
System.out.println(extension);
// → html
```


### CookieGenerator

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/CookieGenerator.html)
* [github] (https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util/CookieGenerator.java)

クッキー生成のヘルパークラス。

#### addCookie

クッキーを追加する。

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletResponse response) {

    String cookieValue = RandomStringUtils.randomAlphabetic(18);

    CookieGenerator cookieGenerator = new CookieGenerator();
    cookieGenerator.setCookieDomain("localhost");
    cookieGenerator.setCookieMaxAge(600);
    cookieGenerator.setCookieName("myCookie");
    cookieGenerator.addCookie(response, cookieValue);

    return "util/s1";
  }

}
```


#### removeCookie

クッキーを削除する。

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletResponse response) {

    CookieGenerator cookieGenerator = new CookieGenerator();
    cookieGenerator.setCookieName("myCookie");
    cookieGenerator.removeCookie(response);

    return "util/s1";
  }

}
```


### WebUtils

* [javadoc api] (http://docs.spring.io/spring-framework/docs/4.3.3.RELEASE/javadoc-api/org/springframework/web/util/WebUtils.html)
* [github] (https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/util/WebUtils.java)

Webアプリケーションのためのユーティリティークラス。

#### getTempDir

サーブレットコンテナが管理する一時ディレクトリを取得する。

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @Autowired
  ServletContext context;

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1() {

    File tempDir = WebUtils.getTempDir(context);
    System.out.println(tempDir.getName());
    // → ROOT
    System.out.println(tempDir.getPath());
    // → D:\temp\work\Tomcat\localhost\ROOT 

    return "util/s1";
  }

}
```

Spring Bootではapplication.propertiesのserver.tomcat.basedirで任意のディレクトリを指定できる。

```yaml:application.yml
server:
  tomcat:
    basedir: D:\temp
```


#### getRealPath

Webアプリケーション内のパスの実際のパスを取得する。

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @Autowired
  ServletContext context;

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1() {

    try {
      String realPath = WebUtils.getRealPath(context, "/js/main.js");
      System.out.println(realPath);
      // → C:\Users\Username\AppData\Local\Temp\tomcat-docbase.7439785954265898853.9000\js\main.js
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }

    return "util/s1";
  }

}
```


#### getSessionId

セッションIDを取得する。（セッションが存在しない場合はnull）

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletRequest request) {
 
    String sessionId = WebUtils.getSessionId(request);
    System.out.println(sessionId);
    // → EF5720E1A6A3C47FA3F1D2D31315AB98

    return "util/s1";
  }

}
```


#### setSessionAttribute

セッション属性に値をセットする。
既存のセッション属性にnullをセットすると削除する。

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletRequest request) {
 
    Date current = new Date();
    WebUtils.setSessionAttribute(request, "current", current);

    return "util/s1";
  }

}
```


#### getSessionAttribute

セッション属性の値を取得する。（存在しない場合はnull）

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletRequest request) {

    Date current = (Date) WebUtils.getSessionAttribute(request, "current");
    System.out.println(current);
    // → Thu Oct 26 21:24:34 JST 2016

    return "util/s1";
  }

}
```


#### getRequiredSessionAttribute

セッション属性の値を取得する。（存在しない場合は例外をスローする）

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletRequest request) {

    try {
      Date current = (Date) WebUtils.getRequiredSessionAttribute(request, "current");
      System.out.println(current);
      // → Thu Oct 26 21:24:34 JST 2016
    } catch (IllegalStateException e) {
      e.printStackTrace();
    }

    return "util/s1";
  }

}
```


#### getCookie

指定する名前のクッキーの値を取得する。（存在しない場合はnull）

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s1", method = RequestMethod.GET)
  public String s1(HttpServletRequest request) {

    Cookie cookieValue = WebUtils.getCookie(request, "myCookie");
    System.out.println(cookieValue);
    // → VIancecCFQaSzBaEsx

    return "util/s1";
  }

}
```


#### hasSubmitParameter

指定する名前のパラメータが`type="submit"`のときtrueを返す。

```html
<form action="/util/s2" method="POST" class="form-horizontal">
  <div class="form-group">
    <label for="name" class="col-sm-2 control-label">name</label>
    <div class="col-sm-10">
      <input class="form-control" id="name" name="name" type="text" />
    </div>
  </div>
  <div class="form-group">
    <label for="email" class="col-sm-2 control-label">email</label>
    <div class="col-sm-10">
      <input class="form-control" id="email" name="email" type="email" />
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" name="send" class="btn btn-default">送信</button>
    </div>
  </div>
</form>
```

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s2", method = RequestMethod.POST)
  public String s2(HttpServletRequest request) {

    Boolean isSubmit = WebUtils.hasSubmitParameter(request, "send");
    System.out.println(isSubmit);
    // → true
    Boolean hasRegist = WebUtils.hasSubmitParameter(request, "regist");
    System.out.println(hasRegist);
    // → false

    return "util/s2";
  }

}
```


#### findParameterValue

指定する名前のパラメータの値を取得する。

```html
<form action="/util/s2" method="POST" class="form-horizontal">
  <div class="form-group">
    <label for="name" class="col-sm-2 control-label">name</label>
    <div class="col-sm-10">
      <input class="form-control" id="name" name="name" type="text" />
    </div>
  </div>
  <div class="form-group">
    <label for="email" class="col-sm-2 control-label">email</label>
    <div class="col-sm-10">
      <input class="form-control" id="email" name="email" type="email" />
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" name="send" class="btn btn-default">送信</button>
    </div>
  </div>
</form>
```

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s2", method = RequestMethod.POST)
  public String s2(HttpServletRequest request) {

    String email = WebUtils.findParameterValue(request, "email");
    System.out.println(email);
    // → rubytomato@example.com
    String telno = WebUtils.findParameterValue(request, "telno");
    System.out.println(telno);
    // → null

    return "util/s2";
  }

}
```


#### getParametersStartingWith

指定するprefixを持つすべてのパラメータの値をMapで返す。
マップのキーにはprefixを取り除いたパラメータの名前が格納される。

```html
<a href="/util/s3?chk_flg1=on&amp;chk_flg2=on&amp;chk_flg3=off&amp;chk_flg4=on">getParametersStartingWith</a>
```

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s3", method = RequestMethod.GET)
  public String s3(HttpServletRequest request) {

    Map<String, Object> params = WebUtils.getParametersStartingWith(request, "chk_");
    if (!params.isEmpty()) {
      for (Entry<String, Object> e : params.entrySet()) {
        System.out.println("key:" + e.getKey() + " value:" + e.getValue());
        // → key:flg1 value:on 
        // → key:flg2 value:on 
        // → key:flg3 value:off 
        // → key:flg4 value:on 
      }
    }

    return "util/s3";
  }

}
```

**配列パラメータのとき**

```html
<a href="/util/s3?chk_flg=a&amp;chk_flg=b&amp;chk_flg=c&amp;chk_flg=d">getParametersStartingWith</a>
```

```java
Map<String, Object> params = WebUtils.getParametersStartingWith(request, "chk_");
if (!params.isEmpty()) {
  for (Entry<String, Object> e : params.entrySet()) {
    System.out.println("key:" + e.getKey() + " value:" + e.getValue());
    // → key:flg value:[a, b, c, d]
  }
}
```


#### parseMatrixVariables

文字列の行列変数(matrix variables)をパースしてMultiValueMapクラスで返す。

```html
<a href="/util/s3?q=a=10;a=11;b=21,22,23;c=33">parseMatrixVariables</a>
```

```java
@Controller
@RequestMapping(value = "/util")
public class UtilController {

  @RequestMapping(value = "/s3", method = RequestMethod.GET)
  public String s3(HttpServletRequest request) {

    String q = WebUtils.findParameterValue(request, "q");
    System.out.println(q);
    // → a=10;a=11;b=21,22,23;c=33

    MultiValueMap<String, String> mParams = WebUtils.parseMatrixVariables(q);
    if (!mParams.isEmpty()) {
      for (Entry<String, List<String>> e: mParams.entrySet()) {
        for (String value : e.getValue()) {
          System.out.println("key:" + e.getKey() + " value:" + value);
          // → key:a value:10 
          // → key:a value:11 
          // → key:b value:21 
          // → key:b value:22 
          // → key:b value:23 
          // → key:c value:33 
        }
      }
    }

    return "util/s3";
  }

}
```