今天遇到一个很恶心的问题,从ios发过来的post请求怎么都无法识别,可是在web端发送确实很正常的。过程如下:
1.在chrome浏览器里随便打开一个网页,F12打开控制台,然后植入jquery
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", 'http://libs.baidu.com/jquery/1.9.1/jquery.js');
document.getElementsByTagName("head")[0].appendChild(fileref);
2.发送post请求
$.post(
"http://192.168.2.4/app/api/blackList/query/name",
{name: "王刚", currentPage: "1"},
function (txt) {
console.log(txt);
}
)
返回的数据正常:
通过打断点调试发现,
ios端发来的请求>content-type:application/json
web方式发来的请求>content-type:application/x-www-form-urlencoded; charset=UTF-8
到这里,问题就好解决了,前者是一个字符串,可以在代码里加上@RequestBody实现转换,同时,将web传递的content-type修改一下即可(不能直接使用$.post,这对于开发者而言可不够友好)
$.ajax(
{
type: "post",
contentType:"application/json",
url: "http://192.168.2.4/app/api/blackList/query/name",
data: JSON.stringify({name:"王刚",currentPage:"1"}),
success: function(data){
console.log(data)
}
}
)
斟酌再三,决定还是保留对传统web端jquery.post()方式的支持,同时支持ios序列化传递过来的参数,第一版先进行header判断,遇到application/json的content-type,就从request取出inputstream,手动转化
controller的代码如下:
@ApiOperation(value = "姓名查询", notes = "首次访问时currentPage传1")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "名称", required = true, dataType = "String"),
@ApiImplicitParam(name = "currentPage", value = "当前是第几页", required = true, dataType = "String")})
@PostMapping(value = "/api/blackList/query/name")
public String nameQuery(BlackListParam param, HttpServletRequest request) throws IOException {
String contentType = request.getHeader("Content-Type");
if (contentType.endsWith("application/x-www-form-urlencoded")) {
} else if (contentType.endsWith("application/json")) {
String string = HttpToolkit.getContent(request.getInputStream(), "UTF-8");
param = mapper.readValue(string, BlackListParam.class);
}
logger.info("进入nameQuery,name=" + param.getName() + "¤tPage=" + param.getCurrentPage());
int currentPageInt = Integer.parseInt(param.getCurrentPage());
String result = blackListApiService.nameQuery(param.getName(), currentPageInt);
return result;}
HttpToolkit里面的getContent部分的代码:
public static String getContent(InputStream is, String charset) {
String pageString = null;
InputStreamReader isr = null;
BufferedReader br = null;
StringBuffer sb = null;
try {
isr = new InputStreamReader(is, charset);
br = new BufferedReader(isr);
sb = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
pageString = sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null){
is.close();
}
if(isr!=null){
isr.close();
}
if(br!=null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
sb = null;
}
return pageString;
}