LoginSignup
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-01-05

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

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 commandList = mapper.readValue(jsonString, type);

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

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

 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も残しておきます。

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);

    }
}
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して返り値を取得といったことは出来ない。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0