之前项目临时改接口的时候,出现了跨域问题,本来打算用nginx 配置CROS解决,但是一直没生效,后来改用非官方的jsonp解决方案前后端代码如下:
后端接口:
/**
* 根据openId获取会员信息
* @return 会员的openId为 @openId 获取会员信息(姓名、手机号、职业、营业单位、所在地区、详细地址)
*/
@ResponseBody
@RequestMapping(value = "/mobile/get-by-openid",method = RequestMethod.GET)
public String getByYouYuOpenId(@RequestParam("callback") String callback, @RequestParam("youyuOpenId")String youyuOpenId){
String openId = youyuOpenidMapperService.get(youyuOpenId);
if(openId==null){
log.info("获取youyuOpenId失败。。。openId={},youyuOpenId={}",openId,youyuOpenId);
Result result = failResponse(ErrorCode.DATA_NOT_EXISTS, "redis通过youyuOpenId获取openId失败");
return callback+"("+new Gson().toJson(result)+")";
}
MemberInfoYouYu memberInfoYouYu = memberService.getByOpenId(openId);
if(memberInfoYouYu == null){
log.info("通过openId获取会员信息为空 openId={}",openId);
Result result = failResponse(ErrorCode.DATA_NOT_EXISTS, "通过openId获取会员信息为空");
return callback+"("+new Gson().toJson(result)+")";
}
Result result = ResultUtils.success("memberInfoYouYu",memberInfoYouYu);
return callback+"("+new Gson().toJson(result)+")";
}
前端代码如下:
jQuery(document).ready(function(){
$.ajax({
type: "get",
async: false,
url: "http://xxxx.com/mobile/get-by-openid?youyuOpenId=adfghi-Pur-vaQFwjyISkwsbk&callback=callback",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
//因为请求的是json文件,json不是服务器端的动态语言不能进行解析,如果是php或者其他的服务器端语言,则不用写死函数名
success: function(json){
//...
},
error: function(){
//...
}
});
});
这样处理的确实现了跨域但是发现返回的json中出现了中文乱码问题,这很大可能是由于response没有进行编码所致,所以尝试在后端的接口的@RequestMapping()中加入produces="text/html;charset=UTF-8"属性。
果然,后来乱码成功解决了。
/**
* 根据openId获取会员信息
* @return 会员的openId为 @openId 获取会员信息(姓名、手机号、职业、营业单位、所在地区、详细地址)
*/
@ResponseBody
@RequestMapping(value = "/mobile/get-by-openid",method = RequestMethod.GET, produces = "text/json;charset=UTF-8")
public String getByYouYuOpenId(@RequestParam("callback") String callback, @RequestParam("youyuOpenId")String youyuOpenId){
getResponse().setCharacterEncoding("UTF-8");
String openId = youyuOpenidMapperService.get(youyuOpenId);
if(openId==null){
log.info("获取youyuOpenId失败。。。openId={},youyuOpenId={}",openId,youyuOpenId);
Result result = failResponse(ErrorCode.DATA_NOT_EXISTS, "redis通过youyuOpenId获取openId失败");
return callback+"("+new Gson().toJson(result)+")";
}
MemberInfoYouYu memberInfoYouYu = memberService.getByOpenId(openId);
if(memberInfoYouYu == null){
log.info("通过openId获取会员信息为空 openId={}",openId);
Result result = failResponse(ErrorCode.DATA_NOT_EXISTS, "通过openId获取会员信息为空");
return callback+"("+new Gson().toJson(result)+")";
}
Result result = ResultUtils.success("memberInfoYouYu",memberInfoYouYu);
return callback+"("+new Gson().toJson(result)+")";
}
总结:这个问题应该算是比较基础的问题了,因为这是springMvc最基础的部分,当然由于很多项目的框架在web.xml用Filter做了编码处理,所以这个问题还是在实际正常的大项目开发中比较少见,所以遇到了就总结一下。其实这是关于spring Mvc中@RequestMapping注解的使用。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
【1、 value, method;】
value:指定请求的实际地址,指定的地址可以是URI Template 模式;
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
【2、consumes,produces;】
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
【3、 params,headers;】
params: 指定request中必须包含某些参数值时,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。