【问题标题】:Error "400 Bad Request" The request sent by the client was syntactically incorrect错误“400 Bad Request”客户端发送的请求在语法上不正确
【发布时间】:2015-12-23 04:48:59
【问题描述】:

我是 jQuery 新手,正在尝试使用 Ajax 调用 Web 服务。这似乎是相当简单的代码,但不知何故无法理解其失败的原因。我尝试了所有可能的方法(我能想到的),但不知何故没有让它发挥作用。

jsp代码:

function tmpData() {
  var dataObject = JSON.stringify({
    'empfname': "First Name",
    'emplname': "Last Name"
});

alert("dataObject=" + dataObject);

$.ajax({
    url:"http://localhost:8080/OnlineStore/kmsg/grocery/tmpinfo",
    type:"POST",
    contentType: 'application/json',
    data: dataObject,
    done: setData,
    fail: displayError()
 });
}; // end of function

控制器:

@RestController
@RequestMapping("/kmsg/grocery")
public class TmpSvcImpl implements TmpSvcInt {
@Override
@RequestMapping(value = "/tmpinfo", method = RequestMethod.POST, headers = "Accept=application/json")
public @ResponseBody Map<String, Object> setData(@RequestBody final Emp employee1) throws Exception {

    System.out.println("employee1=" + employee1);
    String fname = employee1.getEmpfname();
    String lname = employee1.getEmplname();
    System.out.println("fn=" + fname ) ;
    System.out.println("ln=" + lname ) ;

    return null;
  }
}

模型类:

public class Emp implements Serializable {

private static final long serialVersionUID = 1L;
String empfname;
String emplname;

public String getEmpfname() {
    return empfname;
}
public void setEmpfname(String empfname) {
    this.empfname = empfname;
}
public String getEmplname() {
    return emplname;
}
public void setEmplname(String emplname) {
    this.emplname = emplname;
}

public Emp(String fn, String ln){
    this.empfname = fn ;
    this.emplname = ln ;
}

@Override
public String toString() {
    return "Emp {empfname=" + empfname + ", emplname=" + emplname + "}" ;
  }
}

【问题讨论】:

  • 我可能是错的,但我不认为你 JSON.stringify 你的 dataObject 时发送它;我相信 jQuery 可以解决这个问题。
  • @dawsonc623 结果是一样的。收到错误的请求错误。
  • 可能应该先问这个问题,但是您的控制器是否受到攻击?
  • @dawsonc623 是的。如果我发送一个常规字符串控制器也会显示它。
  • @Harry 你打开调试日志了吗?我认为这里正在发生更深层次的事情,在提交请求时查看是否产生了任何堆栈跟踪将非常有帮助。

标签: java jquery ajax spring spring-mvc


【解决方案1】:

添加默认构造函数到您的Emp 类,以便Jackson 能够创建它的实例,如下所示:

public class Emp implements Serializable {

    private static final long serialVersionUID = 1L;
    public String empfname;
    public String emplname;

    public String getEmpfname() {
        return empfname;
    }

    public void setEmpfname(String empfname) {
        this.empfname = empfname;
    }

    public String getEmplname() {
        return emplname;
    }

    public void setEmplname(String emplname) {
        this.emplname = emplname;
    }

    public Emp(String fn, String ln) {
        this.empfname = fn;
        this.emplname = ln;
    }

    /**
     * default constructor
     */
    public Emp() {

    }

    @Override
    public String toString() {
        return "Emp {empfname=" + empfname + ", emplname=" + emplname + "}";
    }
}

【讨论】:

  • 如果 OP 不想要一个默认构造函数,为什么要添加一个默认构造函数?我们也不知道是否使用了杰克逊。
  • @zeroflagL : @RequestBody 使用预配置的 HttpMessageConverter 之一将请求转换为对象,如果 OP 请求是 JSON,则需要 MappingJackson2HttpMessageConverter - docs.spring.io/spring/docs/current/javadoc-api/org/…
  • 您需要一个消息转换器,是的,但不是“预配置”的。
  • 是的,简单点MappingJackson2HttpMessageConverter 我相信是个不错的选择。
  • @Harry:如果可行,请接受答案 - meta.stackexchange.com/questions/5234/…
【解决方案2】:

在您描述的块中:

@RestController
@RequestMapping("/kmsg/grocery")
public class TmpSvcImpl implements TmpSvcInt {
    @Override
    @RequestMapping(
             value = "/tmpinfo", 
             method = RequestMethod.POST, 
             headers = "Accept=application/json")
    public @ResponseBody Map<String, Object> setData(@RequestBody final Emp employee1) throws Exception {
        System.out.println("employee1=" + employee1);
        String fname = employee1.getEmpfname();
        String lname = employee1.getEmplname();
        System.out.println("fn=" + fname ) ;
        System.out.println("ln=" + lname ) ;
        return null;
    }
}

为此用例指定“接受”标头并不正确。如果您希望此方法仅在内容类型为“application/json”时响应,则必须添加“application/json”的消费属性。正如评论指出的那样,这不是绝对必要的。添加 'application/json' 的生产属性将确保 Spring 将尝试将返回的内容编组为 JSON 结构。

@RestController
@RequestMapping("/kmsg/grocery")
public class TmpSvcImpl implements TmpSvcInt {
    @Override
    @RequestMapping(
             value = "/tmpinfo", 
             method = RequestMethod.POST, 
             consumes = "application/json",
             produces = "application/json")
    public @ResponseBody Map<String, Object> setData(@RequestBody final Emp employee1) throws Exception {
        System.out.println("employee1=" + employee1);
        String fname = employee1.getEmpfname();
        String lname = employee1.getEmplname();
        System.out.println("fn=" + fname ) ;
        System.out.println("ln=" + lname ) ;
        return null;
    }
}

【讨论】:

  • X-Requested-With 标头由 jQuery 设置。不是每个 AJAX 调用都有它。缺少consumes 表示“接受一切”,因此在这种情况下没有必要。 "Specifying the 'Accept' header is not really correct"这句话是正确的,但不是因为你提到的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多