だいぶ昔に書いた奴が限定共有になっていたので公開
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して返り値を取得といったことは出来ない。