【问题标题】:SPRING MVC can't get params from jsonSPRING MVC 无法从 json 获取参数
【发布时间】:2015-07-28 08:44:49
【问题描述】:

我的 MVC 服务器有问题。当我发布我的 JSON 时:

{
  "shipName":"shfdsfds",
  "signal":"fdsfsd321",
  "longitude":43,
  "latitude":32,
  "maxSpeed":342
} 

使用 PUT 方法并在 Signal 类中定义了两个构造函数:

public Signal(){
}

public Signal(String shipName, String signal, int latitude, int longitude,
        int maxSpeed) {
    ShipName = shipName;
    Signal = signal;
    Latitude = latitude;
    Longitude = longitude;
    MaxSpeed = maxSpeed;
}

每次我收到状态码:200-Ok,但婴儿车的值错误(addSignal:0)。

我的控制者:

@RequestMapping(value = "/addSignal", method = RequestMethod.PUT)
@ModelAttribute
public ResponseEntity<Signal> add(
        @ModelAttribute Signal signal) throws SQLException,
        ClassNotFoundException {
    System.out.println("addSignal: "+signal.getMaxSpeed());
    return new ResponseEntity<Signal>(signal, HttpStatus.OK);

}

当我尝试删除第一个构造函数 (public Signal(){}) 时,我收到错误: 状态码:500 内部服务器错误

控制台:

maj 16, 2015 3:18:23 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [server] in context with path [/shipserver] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mkozykowski.api.Signal]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.mkozykowski.api.Signal.<init>()] with root cause
java.lang.NoSuchMethodException: com.mkozykowski.api.Signal.<init>()
    at java.lang.Class.getConstructor0(Class.java:2892)
    at java.lang.Class.getDeclaredConstructor(Class.java:2058)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:105)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:101)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:833)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:651)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

---------编辑--------- 我改变了我的控制器:

@RequestMapping(value = "/addSignal", method = RequestMethod.PUT, produces = "application/json")
public ResponseEntity<Signal> add(
        @RequestBody Signal signal) throws SQLException,
        ClassNotFoundException {
    System.out.println("addSignal: "+signal.getMaxSpeed());
    return new ResponseEntity<Signal>(signal, HttpStatus.OK);
}

现在在 Signal 类中我有一个构造函数:

public Signal(@JsonProperty("shipName")String shipName,@JsonProperty("signal")String signal,
            @JsonProperty("latitude")int latitude, @JsonProperty("longitude")int longitude,
            @JsonProperty("maxSpeed")int maxSpeed) {
        ShipName = shipName;
        Signal = signal;
        Latitude = latitude;
        Longitude = longitude;
        MaxSpeed = maxSpeed;
    }

通过 RESTClient 发送 Json 我添加了 header:Content-Type:application/json。 现在我收到错误:

HTTP 状态 415

在我的控制台中什么也没有出现。

【问题讨论】:

  • 您没有使用绑定(即请求参数绑定到对象参数)。你想要编组。而不是@ModelAttribtue(用于绑定)使用@RequestBody 将主体转换为对象。此外,您可能希望方法上的 @ModelAttribute@ResponseBody 以将 JSON 而不是对象返回给客户端。

标签: java json spring rest model-view-controller


【解决方案1】:

我觉得你应该使用@RequestBody 而不是@ModelAttribute。 为了确保 json 反序列化器使用 json 数据正确构造您的类,我建议使用 @JsonProperty("propertyName") 注释构造函数参数,其中 propertyName 匹配 json 属性名称。

---编辑---

您确定您正确设置了标题吗?因为你的代码对我来说很好用。

【讨论】:

  • 当我取消注释我的第一个构造函数 (public Signal(){}) 时,一切正常。奇怪...
  • 我明白了。这样你的数据被编码为form-data,你需要发送json(你可以用postman在“raw”选项卡中编写json代码)。
猜你喜欢
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多