简体   繁体   English

无法使用Spring使用Java REST Api接收JSON数据

[英]Cannot receive json data with java REST Api using Spring

My database seems to be connected properly, I have not included all the classes for my rest application. 我的数据库似乎连接正常,我没有包括我的休息应用程序的所有类。 I am trying to parse this json body: 我试图解析这个json体:

{ "firstName":"user", "lastName":"user", "email":"test@test.com", "password":"123" } {“firstName”:“user”,“lastName”:“user”,“email”:“test@test.com”,“password”:“123”}

with the HTTP POST method but I am returned with: 使用HTTP POST方法,但我返回:

{
    "timestamp": "2019-03-19T16:20:01.121+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
    "path": "/users"
}

The Error message: 错误消息:

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
    2019-03-19 12:19:50.892  INFO 25589 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2019-03-19 12:19:50.893  INFO 25589 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.16]
    2019-03-19 12:19:50.899  INFO 25589 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/vince/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
    2019-03-19 12:19:50.985  INFO 25589 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2019-03-19 12:19:50.986  INFO 25589 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1231 ms
    2019-03-19 12:19:51.102  INFO 25589 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    2019-03-19 12:19:51.316  INFO 25589 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    2019-03-19 12:19:51.356  INFO 25589 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
        name: default
        ...]
    2019-03-19 12:19:51.394  INFO 25589 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.3.7.Final}
    2019-03-19 12:19:51.395  INFO 25589 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
    2019-03-19 12:19:51.478  INFO 25589 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
    2019-03-19 12:19:51.558  INFO 25589 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
    2019-03-19 12:19:51.949  INFO 25589 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
    2019-03-19 12:19:52.273  INFO 25589 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
    2019-03-19 12:19:52.299  WARN 25589 --- [           main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
    2019-03-19 12:19:52.432  INFO 25589 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2019-03-19 12:19:52.435  INFO 25589 --- [           main] c.v.app.ws.MobileAppWsApplication        : Started MobileAppWsApplication in 2.93 seconds (JVM running for 3.492)
    2019-03-19 12:20:00.945  INFO 25589 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
    2019-03-19 12:20:00.945  INFO 25589 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
    2019-03-19 12:20:00.950  INFO 25589 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
    UserEntity{id=0, userId='testId', firstName='null', lastName='null', email='null', encryptedPassword='test', emailVerificationToken='testing', emailVerificationStatus=false}
    2019-03-19 12:20:01.091  WARN 25589 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1048, SQLState: 23000
    2019-03-19 12:20:01.091 ERROR 25589 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column 'encrypted_password' cannot be null
    2019-03-19 12:20:01.095 ERROR 25589 --- [nio-8080-exec-1] o.h.i.ExceptionMapperStandardImpl        : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
    2019-03-19 12:20:01.111 ERROR 25589 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

    java.sql.SQLIntegrityConstraintViolationException: Column 'encrypted_password' cannot be null
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.15.jar:8.0.15]
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.15.jar:8.0.15]


        [ . . .] 

My UserServiceImpl classes to help understand context: 我的UserServiceImpl类有助于理解上下文:

package com.vincentaudette.app.ws.service.impl;

import com.vincentaudette.app.ws.UserRepository;
import com.vincentaudette.app.ws.io.entity.UserEntity;
import com.vincentaudette.app.ws.service.UserService;
import com.vincentaudette.app.ws.shared.dto.UserDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;

    @Override
    public UserDto createUser(UserDto userDto) {

        UserEntity userEntity = new UserEntity();

        userEntity.setEncryptedPassword("test");
        userEntity.setEmailVerificationToken("testing");
        userEntity.setUserId("testId");

        System.out.println(userEntity.toString());

        BeanUtils.copyProperties(userDto, userEntity);

        UserEntity storedUserDetails = userRepository.save(userEntity);

        UserDto returnDto = new UserDto();

        BeanUtils.copyProperties(storedUserDetails,returnDto);

        return returnDto;
   }
}

package com.vincentaudette.app.ws;

import com.vincentaudette.app.ws.io.entity.UserEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends CrudRepository<UserEntity, Long> {
}

package com.vincentaudette.app.ws.io.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;

@Entity(name = "users")
public class UserEntity implements Serializable {

    private static final long serialVersionUID = 2L;

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable = false)
    private String userId;

    @Column(nullable = false, length = 50)
    private String firstName;

    @Column(nullable = false, length = 50)
    private String lastName;

    @Column(nullable = false, length = 120, unique = true)
    private String email;

    @Column(nullable = false)
    private String encryptedPassword;

    private String emailVerificationToken;

    @Column(nullable = false)
    private Boolean emailVerificationStatus = false;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEncryptedPassword() {
        return encryptedPassword;
    }

    public void setEncryptedPassword(String encryptedPassword) {
        this.encryptedPassword = encryptedPassword;
    }

    public String getEmailVerificationToken() {
        return emailVerificationToken;
    }

    public void setEmailVerificationToken(String emailVerificationToken) {
        this.emailVerificationToken = emailVerificationToken;
    }

    public Boolean getEmailVerificationStatus() {
        return emailVerificationStatus;
    }

    public void setEmailVerificationStatus(Boolean emailVerificationStatus) {
        this.emailVerificationStatus = emailVerificationStatus;
    }
}

I don't know exactly what technology are you using, but it seems hibernate is configured to use undersore naming. 我不知道您使用的是什么技术,但似乎hibernate配置为使用underore命名。 So you are sending "encryptedPassword" column to the database where it is expecting "encrypted_password". 因此,您要将“encryptedPassword”列发送到期望“encrypted_pa​​ssword”的数据库。

As this column is not null, it throws an error. 由于此列不为null,因此会引发错误。

Have a look at this answer here. 在这里看看这个答案

I solved by setting attributes after copying properties from userDto: 我通过从userDto复制属性后设置属性解决了:

UserEntity userEntity = new UserEntity();
BeanUtils.copyProperties(userDto, userEntity);

userEntity.setEncryptedPassword("test");
userEntity.setEmailVerificationToken("testing");
userEntity.setUserId("testId");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM