1. ホーム
  2. java

[解決済み] com.fasterxml.jackson.databind.exc.MismatchedInputException: START_ARRAY トークンからオブジェクトのインスタンスをデシリアライズできません。

2022-02-16 19:05:02

質問

MismatchedInputExceptionが発生する。ここで多くの質問を検索しましたが、主にJSONMappingExceptionが見つかりました。この2つは同じなのか違うのかわかりません。

以下はその実体です。

@Entity
@Table
@NamedQueries({
    @NamedQuery(name="User.findAll", query="SELECT u FROM User u"),
    @NamedQuery(name="User.findByEmail", query="SELECT u FROM User u WHERE u.email=:pEmail")
})
public class User {

@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid2")
@GeneratedValue(generator = "idGenerator")
private String id;
private String firstName;
private String lastName;

@Column(unique=true)
private String username;

@Column(unique=true)
private String email;
private String password;
private String role;
}

を、すべてのゲッターとセッターを適切に配置することです。

以下は、コントローラマッピングの関数です。

@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User create(@RequestBody User user) {
        return service.create(user);
    }

以下はサービスです。

@Override
    @Transactional
    public User create(User user) {
        User existing = repository.findByEmail(user.getEmail());
        if(existing == null){
            repository.create(user);
        }
        return user;
    }

以下はリポジトリです。

@Override
    public User findByEmail(String email) {
        TypedQuery<User> query = em.createNamedQuery("User.findByEmail", User.class);
        query.setParameter("pEmail", email);
        List<User> users = query.getResultList();
        if(users != null && users.size()==1){
            return users.get(0);
        }
        return null;
    }

    @Override
    public User create(User user) {
        em.persist(user);
        return user;
    }

以下は、私が使用した依存関係です。

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0.pr2</version>
        </dependency>
<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.9.Final</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

Postmanでテストしています。フロントエンドはまだ作っていません。以下は、私が送信しているJSONです。

[{
    "firstName": "hgf",
    "lastName": "frew",
    "username": "erf",
    "email": "bgghjk",
    "password": "bgte",
    "role": "trrere"
  }
]

最後に、コンソールログを以下に示します。

Thu May 11 13:56:43 CDT 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
May 11, 2017 1:57:52 PM org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleHttpMessageNotReadable
WARNING: Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of priyanka.movieflix.entity.User out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Can not deserialize instance of priyanka.movieflix.entity.User out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 1]

何がこの例外を引き起こしているのか、よくわかりません。アプリケーションを起動すると、データベース内にテーブルが正しく作成され、GETリクエストでも正しくデータが取得されています。

どうすればいいですか?

をマッピングしました。 RequestBody を1つの User オブジェクトを送信していますが、JSONの配列で送信しています。

[{
    "firstName": "hgf",
    "lastName": "frew",
    "username": "erf",
    "email": "bgghjk",
    "password": "bgte",
    "role": "trrere"
  }
]

代わりに以下のようにJSONオブジェクトを送信する必要があります。

{
    "firstName": "hgf",
    "lastName": "frew",
    "username": "erf",
    "email": "bgghjk",
    "password": "bgte",
    "role": "trrere"
}

のコレクションを受け取るように、コントローラのマッピングを変更します。 User オブジェクトを

@RequestBody List<User> users