ajax请求从js传json数据到后场及接受方式—用或者不用RequestBody的情况及后场返回

参考网上队友的帖子:传递JSON数据有没有必要用RequestBody?https://www.cnblogs.com/NJM-F/p/10407763.html

 
1.不使用RequestBody时是这样的:

前端参数可以直接使用JSON对象:

//此时请求的ContentType默认是application/x-www-form-urlencoded:
var user= {
                "username" : username,
                "password" : password,
                "rememberMe":rememberMe
          };
$.ajax({
    url : "http://...../jsontest.do",
    type : "POST",
    async : true,
    data : user,
    dataType : ‘json‘,
    success : function(data) {
    }
});

后端参数的可以用java对象接收,也可以用数据类型单独接收:

@RequestMapping("/jsontest.do")
public void test(User user,String username,String password,Boolean rememberMe){
    System.out.println(user);
    System.out.println("username: " + username);
    System.out.println("password: " + password);
    System.out.println("rememberMe: " + rememberMe);
    
}

2.而使用RequestBody是这样的:

参考:https://blog.csdn.net/walkerJong/article/details/7520896

作用:

      i) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;

      ii) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机:

A) GET、POST方式提时, 根据request header Content-Type的值来判断:

    application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理);
    multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
    其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);
B) PUT方式提交时, 根据request header Content-Type的值来判断:

    application/x-www-form-urlencoded, 必须;
    multipart/form-data, 不能处理;
    其他格式, 必须;
说明:request的body部分的数据编码格式由header部分的Content-Type指定;


前端使用application/json的时候,必须要将JSON对象转换为JSON字符串

//需要使用JSON.stringify()将JSON对象转化为JSON字符串
var user= {
                "username" : username,
                "password" : password
          };
$.ajax({
        url : "http://...../jsontest.do",
        type : "POST",
        async : true,
        contentType: "application/json; charset=utf-8",//将JSON对象转换为JSON字符串
        data : JSON.stringify(user),
        dataType : ‘json‘,
        success : function(data) {
        }
 });

后端参数要用@RequestBody注解加java对象/map对象/字符串 接收,如果请求的地址后面有参数,则形参可以新增该参数的接收

//这种方式下所有的参数都只能封装在User对象中,不能单独设置参数
@RequestMapping("/jsontest")
//用java对象接收
public void test(@RequestBody User user  ){
    String username = user.getUsername();
    String password = user.getPassword();
}

或者

@RequestMapping("/jsontest")
//用map对象接收,再从map对象中根据key值获取value值
public void test(@RequestBody Map map  ){
    String username = map.get("username").toString();
    String password = map.get("password").toString();
}

或者

 public void test(@RequestBody String jsonData) {
//用字符串接收,再将字符串转为json对象,最后再解析为具体的对象
    JSONObject jsonObject = JSON.parseObject(jsonData);
    String username= jsonObject.getString("username");
    String username= jsonObject.getString("password");
 }

第1种有以下优点: 
1.前端传递数据不用转换为json字符串:即不用JSON.stringify(user) 
2.后端接受的参数很灵活,即可以封装为User对象,亦可以使用单个参数username,rememberMe,甚至User对象和单个rememberMe参数混合使用都可以

第2种优点:

1.前端ajax请求传入比较复杂的数据格式时,用@RequestBody注解比较好(个人理解)

2.使用@RequestBody时,在ajax请求的地址后边也可以加上参数,然后在后台的controller参数中获取

例如

{var params = {
        id:id,
        taskPhones:taskPhones,
        groupId:groupId,
        planType:planType,
        scheduledTimeStr:scheduledTimeStr,
        taskName:taskName,
        templateContent:templateContent,
        templateId:templateId,
        taskTemplateValueList:taskTemplateValueList,
        smilResourceId:smilResourceId,
    }

    submit(params, ‘0‘);
}

function submit(params,isTemp){
    $.ajax({
        url: WEB_ROOT + "/mall/task/saveTaskForEdit?isTemp="+isTemp,
        type : "POST",
        dataType : "JSON",
        contentType:"application/json",
        data: JSON.stringify(params),
        success: function (data) {
            if (data.success) {
                var taskId=data.data;
                msgInfoModal("成功",‘保存成功‘,function () {
                    window.location = WEB_ROOT + "/mall/task/taskIndex";
                    // window.location = WEB_ROOT + "/mall/task/editTask?id=" + taskId;
                },true);
                tab.alertReload(‘成功‘,‘保存成功‘,false,"toEdit("+demandId+")");
            } else {
                msgInfoModal("失败",data.msg);
            }
        }
    });
}
的用法

@ResponseBody
作用: 
  该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:
  返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用

例如

//选择分组
function onChangePhoneGroup(groupId) {
    if (groupId == null || groupId == ‘‘) {
        return;
    }
    var params={
        groupId:groupId
    }
    $.ajax({
        url: WEB_ROOT + "/mall/task/selectGroupPhones",
        type : "POST",
        dataType : "JSON",
        data: params,
        success: function (data) {
            if (!data.success) {
                return;
            }
            var phonesStr=data.data.phonesStr;
            $(‘#taskPhones‘).val(phonesStr);
        }
    });

}

@RequestMapping(value = "/selectGroupPhones")
    @ResponseBody
    public R selectGroupPhones(Long groupId) throws Exception{
        if (groupId == null) {
            return R.failure("error");
        }
        Long staffId = StaffUtil.getStaffUserId(session).longValue();

        List<String> phones = itPhonesGroupSV.selectPhoneNosByDataUserIdAndGroupId(staffId, groupId);

        String phonesStr=null;
        if (phones != null && phones.size() > 0) {
            phonesStr = phones.stream()
                    .collect(Collectors.joining(";"));
        }

        Map<String, Object> data = new HashMap<>();

        data.put("phones", phones);
        data.put("phonesStr", phonesStr);
        return R.success(data);
    }

4.返回的是页面时

js

type值为html,返回的参数page为页面,用html接收:

/**
 * 点击预览按钮
 */
function smsPreLook() {
    var id= $("#taskId").val();
    var isdetail=true;
    var param = {
        id: id
    };
    $.ajax({
        url: WEB_ROOT + "/mall/task/preLook?isdetail="+isdetail,
        type: "html",//返回类型为html
        data: JSON.stringify(param),
        contentType:"application/json",
        method: "post",
        success: function (page) {
            $("#preLook").html(page);//返回的是页面
            $(‘#preLookModal‘).modal(‘show‘);
        }
    });
}

java:

返回类型为String,返回值为页面地址字符串

/**
     * 预览显示
     */
    @RequestMapping(value = "/preLook")
    public String examineInit(Model model, @RequestBody TaskVO taskVO, Boolean isdetail) throws Exception {
        AuthStaffVO staff = StaffUtil.getStaffVO(session);
        if (isdetail && taskVO.getId() != null) {
            taskVO = itTaskSV.selectTaskVOById(taskVO.getId());
        } else {
            //校验文本内容的权限(部分自定义的话,只能用模板;完全自定义可以不用模板)
            if (TaskConstant.TASK_RIGHT_1.equals(staff.getTaskRight())) {
                //必须使用模板
                if (taskVO.getTemplateId() == null) {
                    return null;// R.failure("请选择模板~")
                }
                setTaskSmsMsgContentByTemplate(taskVO);
            } else if (TaskConstant.TASK_RIGHT_2.equals(staff.getTaskRight())) {
                //可以不用模板
                if (taskVO.getTemplateId() != null) {
                    setTaskSmsMsgContentByTemplate(taskVO);
                } else {
                    taskVO.setSmsMsgContent(taskVO.getTemplateContent());
                }
            } else {
                return null;//R.failure("您当前没有权限进行此操作哦~");
            }
        }
        List<TaskVO> taskVOList = new ArrayList<TaskVO>();
        try {
            taskVOList = itTaskSV.selectTaskVOList(taskVO);
        } catch (Exception e) {
            log.error("短信任务管理(后台)--数字短信预览异常", e);
        }
        model.addAttribute("taskVOList", taskVOList);
        return "homeMain/myCenter/task/mall-smsPreLook";
    }

相关推荐