jackson Sping Boot 3.1控制器中的类型错误Application/JSON

roqulrg3  于 2023-11-19  发布在  其他
关注(0)|答案(3)|浏览(257)

当我尝试向POST控制器发送数据时,我在POST控制器上得到了一个类型错误。错误似乎很清楚,但解决方案正在逃避我:

环境

Sping Boot 3.1 Java 18 MySQL 8

实体

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@SequenceGenerator(name = "bird_seq", sequenceName = "BIRD_SEQ", initialValue = 100, allocationSize = 50)
@Table(name = "bird")
public class Bird {

@Id
@GeneratedValue(strategy = SEQUENCE, generator = "bird_seq")
private Long id;
@Column(unique = true)
@NotEmpty
private String name;
@Enumerated(EnumType.STRING)
private Sex sex;

@OneToOne(optional = true)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "current_transmitter_id", nullable = true)
private Transmitter currentTransmitter;

@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "bird")
private List<ChickTimer> listChickTimer = new ArrayList<>();

// other fields trimmed

// single property constructor to support testing 

    public Bird(String name) {
    this.name = name;
}

字符串

控制器

@RestController
@RequestMapping("/birds")
@RequiredArgsConstructor
public class KiwiController {

    @Autowired
    private final BirdServiceImpl birdService;

    // tried with and without the consumes/produces
    // also tried consumes = "application/json"
    @PostMapping(value = "/testpost/", consumes = (MediaType.APPLICATION_JSON_VALUE), produces = (MediaType.APPLICATION_JSON_VALUE) )
    ResponseEntity<Bird> BirdCreate(@RequestBody Bird newBird) {
    Bird bird = birdService.save(newBird);
    return new ResponseEntity<>(bird, HttpStatus.CREATED);
}

不支持的媒体类型-错误

{
"timestamp": "2023-09-11T18:29:23.830+00:00",
"status": 415,
"error": "Unsupported Media Type",
"trace": "org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/json;charset=UTF-8' is not supported\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:209)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:163)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:136)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)\r\n\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)\r\n\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:833)\r\n",
"message": "Content-Type 'application/json;charset=UTF-8' is not supported.",
"path": "/birds/testpost/"


}

** Postman **

100d 1xx 1c 1d 1x的字符串

迄今采取的步骤

1.我有另一个控制器在同一个项目工作正常(它甚至不指定媒体类型)
1.已尝试使用@PostMapping(value = "/testpost/", consumes = (MediaType.APPLICATION_JSON_VALUE), produces = (MediaType.APPLICATION_JSON_VALUE) )consumes = "application/json"
1.改变控制器使用另一个类我有测试-它与测试类工作
1.尝试在控制器上的Bird bird = birdService.save(newBird);行上设置断点,但从未到达
1.尝试手动添加“Accept”:“application/json”到postman而不是*/*
1.尝试 curl :
curl -X POST http://localhost:8080/birds/testpost/--header“Content-Type:application/json”-d '{“name”:“bob”}' {“timestamp”:“2023-09-11T09:58:02.903+00:00”,“status”:415,“error”:“Unsupported Media Type”,“trace”:“org.springframework.web.HttpMediaTypeNotSupportedException:Content-Type 'application/json;charset=UTF-8' is not supported
工作的控制器就像这样简单:

@PostMapping(value = "/")
ResponseEntity<Pit> newPIT(@RequestBody PitDto pitDto) {
    Pit createdPit = pitMapper.toEntity(pitDto);
     // some service layer stuff
    Pit savedPit = pitService.savePIT(createdPit);
    return ResponseEntity.ok().body(savedPit);
}


我甚至没有在那个控制器中设置应用程序类型(但是它确实使用Dto)。
我不知道,但怀疑实体上的东西,因为测试实体在该控制器中工作。

更新

在创建了一个新的分支来创建一个最小的、可复制的示例之后,控制器工作了。所以我改回了master,last commit,并开始删除属性。
导致问题的字段是HealthCheck-这是该类:

@NoArgsConstructor
@ToString
@Entity
@Data
@JsonIgnoreProperties({"hibernateLazyInitalizer", "handler"})
@SequenceGenerator(name = "health_check_seq", sequenceName = "HEALTH_CHECK_SEQ", initialValue = 100, allocationSize = 50)
@Table(name = "health_check")
public class HealthCheck {

@Id
@GeneratedValue(strategy = SEQUENCE, generator = "health_check_seq")
private Long id;

@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "bird_id")
private Bird bird;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime catchDateTime;

slsn1g29

slsn1g291#

在这种情况下,答案是与相关/嵌套实体以及它们上的注解有关,以便进行序列化/重复化(Jackson)。
在鸟类类有:

@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "bird")
private List<ChickTimer> listChickTimer = new ArrayList<>();

@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "bird")
private List<Otherclass> listOtherclass = new ArrayList<>();

字符串
为了用@JsonBackReference修复两个属性,我将它们命名为:

@JsonBackReference(value = "bird-chicktimer")
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "bird")
private List<ChickTimer> listChickTimer = new ArrayList<>();

@JsonBackReference(value = "bird-otherclass")
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "bird")
private List<Otherclass> listOtherclass = new ArrayList<>();


我也有一个BackReference在许多方面的一个类,我改变了@JsonManagedReference
application/json错误消息是一个红鲱鱼。

tag5nh1u

tag5nh1u2#

删除所有MediaType.APPLICATION_JSON_VALUE,因为它是APPLICATION_JSON的A String等价物,根据documentation,或者如果你不想删除它,只需将其替换为MediaType.APPLICATION_JSON。为什么?因为我可以在Postman中看到,你确实用json对象请求控制器,而不是用json作为字符串
另外,请确保不要使用Content-Type 'application/json;charset=UTF-8进行请求,只需在不使用utf-8的情况下进行请求。
另外更新,我看到你也在一个实体mappedBy = "bird"两次在不同的领域,你可以改变一个与另一个名称的东西,如mappedBy = "secondBird"

uplii1fm

uplii1fm3#

你的Bird类没有参数的默认构造函数。我认为Sprig因为它而无法将你的JSON转换为Bird类。这是一个猜测,但值得一试。添加

public Bird() {
}

字符串
到类Bird中,或者只是删除构造函数

public Bird(String name) {
    this.name = name;
}

相关问题