簡體   English   中英

Java REST API 發送 GET 請求時出錯,但在 POST 上工作

[英]Java REST API Getting Error when sending GET Request, but works on POST

I have a REST API linked with a Java app that is connected to a database using JDBC that I am currently testing through the Swagger UI.

發送 post 請求完全正常,當給定類型的表為空時發送 GET 請求似乎也返回正常響應,但是一旦我在表中有數據時發送 GET 請求,我會收到以下錯誤。

GET /api/user 500 Server Error
java.lang.reflect.UndeclaredThrowableException: null
    at jdk.proxy2/jdk.proxy2.$Proxy16.getPersons(Unknown Source)
    at module.PersonModule.lambda$new$41b6884b$1(PersonModule.java:23)
    at io.jooby.internal.handler.DefaultHandler.apply(DefaultHandler.java:23)
    at io.jooby.internal.handler.WorkerHandler.lambda$apply$0(WorkerHandler.java:23)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoSuchMethodException: no such constructor: domain.Person.<init>()void/newInvokeSpecial
    at java.base/java.lang.invoke.MemberName.makeAccessException(MemberName.java:974)
    at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1117)
    at java.base/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3649)
    at java.base/java.lang.invoke.MethodHandles$Lookup.findConstructor(MethodHandles.java:2750)
    at org.jdbi.v3.core.mapper.reflect.internal.BeanPropertiesFactory$BeanPojoProperties$PropertiesHolder.<init>(BeanPropertiesFactory.java:202)
    at org.jdbi.v3.core.config.JdbiCaches.lambda$declare$0(JdbiCaches.java:49)
    at org.jdbi.v3.core.config.JdbiCaches$1.lambda$get$1(JdbiCaches.java:63)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
    at org.jdbi.v3.core.config.JdbiCaches$1.get(JdbiCaches.java:63)
    at org.jdbi.v3.core.mapper.reflect.internal.BeanPropertiesFactory$BeanPojoProperties.getProperties(BeanPropertiesFactory.java:81)
    at org.jdbi.v3.core.mapper.reflect.internal.PojoMapper.specialize0(PojoMapper.java:99)
    at org.jdbi.v3.core.mapper.reflect.internal.PojoMapper.specialize(PojoMapper.java:80)
    at org.jdbi.v3.core.result.ResultSetResultIterator.<init>(ResultSetResultIterator.java:38)
    at org.jdbi.v3.core.result.ResultIterable.lambda$of$0(ResultIterable.java:54)
    at org.jdbi.v3.core.result.ResultIterable.stream(ResultIterable.java:228)
    at org.jdbi.v3.core.result.ResultIterable.collect(ResultIterable.java:284)
    at org.jdbi.v3.sqlobject.statement.internal.ResultReturner$CollectedResultReturner.mappedResult(ResultReturner.java:275)
    at org.jdbi.v3.sqlobject.statement.internal.SqlQueryHandler.lambda$configureReturner$0(SqlQueryHandler.java:61)
    at org.jdbi.v3.sqlobject.statement.internal.CustomizingStatementHandler.invoke(CustomizingStatementHandler.java:178)
    at org.jdbi.v3.sqlobject.statement.internal.SqlQueryHandler.invoke(SqlQueryHandler.java:27)
    at org.jdbi.v3.sqlobject.internal.SqlObjectInitData$1.lambda$invoke$0(SqlObjectInitData.java:132)
    at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:44)
    at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:26)
    at org.jdbi.v3.core.LazyHandleSupplier.lambda$invokeInContext$1(LazyHandleSupplier.java:77)
    at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:44)
    at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:26)
    at org.jdbi.v3.core.LazyHandleSupplier.invokeInContext(LazyHandleSupplier.java:76)
    at org.jdbi.v3.sqlobject.internal.SqlObjectInitData$1.call(SqlObjectInitData.java:138)
    at org.jdbi.v3.sqlobject.internal.SqlObjectInitData$1.invoke(SqlObjectInitData.java:132)
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$attach$2(SqlObjectFactory.java:110)
    at org.jdbi.v3.core.internal.OnDemandExtensions.lambda$invoke$5(OnDemandExtensions.java:98)
    at org.jdbi.v3.core.internal.exceptions.Unchecked.lambda$function$4(Unchecked.java:76)
    at org.jdbi.v3.core.internal.OnDemandExtensions.invoke(OnDemandExtensions.java:98)
    at org.jdbi.v3.core.internal.OnDemandExtensions.lambda$createProxy$2(OnDemandExtensions.java:82)
    at org.jdbi.v3.core.Jdbi.callWithExtension(Jdbi.java:476)
    at org.jdbi.v3.core.Jdbi.withExtension(Jdbi.java:463)
    at org.jdbi.v3.core.internal.OnDemandExtensions.lambda$createProxy$3(OnDemandExtensions.java:82)
    ... 8 common frames omitted
Caused by: java.lang.NoSuchMethodError: domain.Person: method 'void <init>()' not found
    at java.base/java.lang.invoke.MethodHandleNatives.resolve(Native Method)
    at java.base/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
    at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
    ... 43 common frames omitted

聲明為拋出錯誤的 PersonModule 的第 23 行具有以下代碼

 public PersonModule(PersonDAO dao){
        
        path("/api/user", () -> {
            get("", ctx -> {
                return dao.getPersons();
            });
            
            post("", ctx -> {
                Person person = ctx.body().to(Person.class);
                if (dao.getPerson(person.getEmail()) == null) {
                    dao.savePerson(person);
                    return ctx.send(StatusCode.CREATED);
                } else {
                    return ctx
                            .setResponseCode(StatusCode.UNPROCESSABLE_ENTITY)
                            .render(new ErrorMessage("That email already exists in the system"));
                }
            });
        });

return dao.getPersons()是第 23 行

獲取人員的 JDBI 代碼是

    @Override
    @SqlQuery("SELECT * FROM PERSON ORDER BY EMAIL")
    @RegisterBeanMapper(Person.class)
    public Collection<Person> getPersons();

和 Person.class 有以下代碼(也包括普通的 getter 和 setter 方法)

 public Person(Integer personID, String email, String password, String firstName, String lastName, String phone, String mobile, String industry, String bio, String city, Boolean active, String findOut, String role, String notes) {
        this.personID = personID;
        this.email = email;
        this.password = password;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
        this.mobile = mobile;
        this.industry = industry;
        this.bio = bio;
        this.city = city;
        this.active = active;
        this.findOut = findOut;
        this.role = role;
        this.notes = notes;
    }

我可以請幫助確定問題所在嗎?

注意: GET 請求稍早進行了測試,似乎工作正常,即使數據庫中有數據。 DAO 的單元測試也沒有錯誤地通過。

在 SQL 查詢中嘗試實際的列名。 而不是這個:

SELECT * FROM PERSON ORDER BY EMAIL

嘗試這個:

SELECT PERSONID, EMAIL, PASSWORD,... FROM PERSON ORDER BY EMAIL

您應該從錯誤輸出中獲得精髓。

它與構造函數 INIT 中的 lambda 代碼相關,沒有這樣的方法 getPersons

有問題的代碼應該有一個異常包裝或添加到構造函數聲明開始,據說至少對於獲取請求代碼,例如 throws ServletException 和 UnavailableException

GET /api/user 500 Server Error
java.lang.reflect.UndeclaredThrowableException: null
    at jdk.proxy2/jdk.proxy2.$Proxy16.getPersons(Unknown Source)
    at module.PersonModule.lambda$new$41b6884b$1(PersonModule.java:23)

    path("/api/user", () -> {
                get("", ctx -> {
                    return dao.getPersons();
                });
            
            

以下引用了一個奇怪的操作,即您使用 getPersons 方法將所有人員放到 Collection object 上,但除了將其返回我假定為“ ctx ”之外,您什么也不做,不幸的是,您實際上並沒有說 object ctx 的類型是。

@Override
@SqlQuery("SELECT * FROM PERSON ORDER BY EMAIL")
@RegisterBeanMapper(Person.class)
public Collection<Person> getPersons();

不知何故,Person class 所需的所有構造函數參數都在帖子中發送,但在代碼中沒有生成 Person class ,我覺得奇怪的是,無論您是否給它一個無參數構造函數作為抽象,它都沒有繼續拋出錯誤class 有,但是想知道是不是把它當作抽象的 class 處理,比較正常的方法是做一個 DTO 數據傳輸 Object 模板和
DAO 數據訪問 Object class 之間的實體,具有調用接口。 而且,getPersons 集合似乎沒有任何用處,何必海量查詢檢索。

我發現了問題,

我的域 class 中的構造函數似乎是錯誤,我通過在當前的 Person.class 上方添加一個空構造函數來修復錯誤

public Person(){
        
    }

public Person(Integer personID, String email, String password, String firstName, String lastName, String phone, String mobile, String industry, String bio, Boolean active, String city,  String findOut, String role, String notes) {
        this.personID = personID;
        this.email = email;
        this.password = password;
        this.firstName = firstName;
        this.lastName = lastName;
        this.phone = phone;
        this.mobile = mobile;
        this.industry = industry;
        this.bio = bio;
        this.city = city;
        this.active = active;
        this.findOut = findOut;
        this.role = role;
    }

現在它工作正常。 如果有人解釋為什么會這樣,我很想知道:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM