Spring3.2でJackson2系を使用し、POSTリクエストを受け付ける


だいぶ昔に書いた奴が限定共有になっていたので公開

```java:JsonController.java
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import local.ma.sakuya.api.business.dto.ngRateResponseDto;
import local.ma.sakuya.api.model.MonitoringDataBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;

@Controller
@RequestMapping("/api/hogehoge/")
public class hogehogeController {

    // コマンド(POSTされたデータを保持する)
    private static final String PAGE_INPUT = "receive/";
    private static final Logger logger = LoggerFactory.getLogger(hogehogeController.class);

    @RequestMapping(value=PAGE_INPUT, method=RequestMethod.POST, produces="application/json; charset=utf-8")
    @ResponseBody
    public String execute(@RequestParam("json_data") String jsonString) throws IOException {

        logger.info("execute() Start.");

        // JacksonでJSON文字列をPOJOへマッピング
        ObjectMapper mapper = new ObjectMapper();
        JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, MonitoringDataBean.class);
        ArrayList<MonitoringDataBean> commandList = mapper.readValue(jsonString, type);
        ArrayList<ngRateResponseDto> dto = new ArrayList<>();

        for (int i=0; commandList.size()>i; i++) {
            MonitoringDataBean beanIndex = commandList.get(i);
            dto.add(new ngRateResponseDto());

            System.out.println(beanIndex);

            ngRateResponseDto dtoIndex = dto.get(i);
            dtoIndex.setPostId(beanIndex.getPostId());
            dtoIndex.setNgWord(beanIndex.getNgWord());
            dtoIndex.setBody(beanIndex.getBody());
        }
        logger.info("execute() End.");
        String res = mapper.writeValueAsString(dto);
        System.out.print(res);
        return res;
    }
}
```

@ResponseBodyアノテーションはビューモデルを通さずにレスポンスを返すのに必要
@RequestParam("json_data") String jsonString)でjson_dataのkeyが付いたPOSTデータを受け取り

あとはJacksonのObjectMapperにPOJOとのマッピングをやってもらうだけ。

ハマったのはここ
JavaType type = mapper.getTypeFactory().constructCollectionType(ArrayList.class, MonitoringDataBean.class);
        ArrayList<MonitoringDataBean> commandList = mapper.readValue(jsonString, type);

以下の様な形式のJSONStringをPOJOへマッピングする際はconstructCollectionTypeに対象のPOJOBean型のArrayListを入れないといけませんでした。

```json:testData
[
{"postId":"1672348_201402","ngRate":"40","ngWord":"LINE","body":"jpgejpge","unixTime":null},{"postId":"1671381_201402","ngRate":"50","ngWord":"LINE","body":"hogehoge","unixTime":null}
]
```

http://jackson.codehaus.org/1.8.8/javadoc/org/codehaus/jackson/map/type/TypeFactory.html#constructCollectionType%28java.lang.Class,%20java.lang.Class%29

```java:
 constructCollectionType

public CollectionType constructCollectionType(Class<? extends Collection> collectionClass,
                                              Class<?> elementClass)

    Method for constructing a CollectionType.

    NOTE: type modifiers are NOT called on Collection type itself; but are called for contained types. 
```

あとは返したい形式に編集してreturnで完了

BeanとDTOも残しておきます。

```java:MonitoringDataBean
import java.io.Serializable;
import lombok.Data;
import org.apache.commons.lang.builder.ToStringBuilder;

@Data
public class MonitoringDataBean implements Serializable {
    private static final long serialVersionUID = -7231993649826586076L;

    private String postId;
    private String ngWord;
    private String body;
    private String unixTime;

    public MonitoringDataBean() {}

    public MonitoringDataBean(String postId, String ngWord, String body, String unixTime) {
        this.postId = postId;
        this.ngWord = ngWord;
        this.body = body;
        this.unixTime = unixTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);

    }
}
```


```java:ngRateResponseDto
import lombok.Data;
import org.apache.commons.lang.builder.ToStringBuilder;

// JSON形式で返却するNG率
@Data
public class ngRateResponseDto {
    private String postId;
    private String ngRate = "0";
    private String ngWord;
    private String body;
    private String unixTime;

    public void setPostId (String postId) {
        this.postId = postId;
    }
    public String getPostId () {
        return postId;
    }

    public void setNgRate () {
        ngRate = "2";
    }
    public String getNgRate () {
        return ngRate;
    }

    public void setNgWord (String ngWord) {
        this.ngWord = ngWord;
    }
    public String getNgWord () {
        return ngWord;
    }
    public void setBody (String body) {
        this.body = body;
    }
    public String getBody () {
        return body;
    }
    public void setUnixTime (String unixTime) {
        this.unixTime = unixTime;
    }
    public String getUnixTime () {
        return unixTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}


```

JSONPはGETしか扱えないのでPOSTして返り値を取得といったことは出来ない。