[英]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. 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.
Sending post Requests work completely fine, and sending GET requests when the table for a given type is empty also seems to return a normal response, however once I send a GET request when there is data in the table, I get the following error.发送 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
Line 23 of PersonModule which is stated as throwing the error has the following code声明为抛出错误的 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"));
}
});
});
With return dao.getPersons()
being line 23 return dao.getPersons()
是第 23 行
Code for the JDBI for get persons is获取人员的 JDBI 代码是
@Override
@SqlQuery("SELECT * FROM PERSON ORDER BY EMAIL")
@RegisterBeanMapper(Person.class)
public Collection<Person> getPersons();
and Person.class has the following code (also includes normal getter and setter methods)和 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;
}
Could I please get some help identifying what the problem is?我可以请帮助确定问题所在吗?
Note : GET requests were tested a little earlier on and seemed to work fine, even with data in the database.注意: GET 请求稍早进行了测试,似乎工作正常,即使数据库中有数据。 Unit tests for the DAO also pass with no errors.
DAO 的单元测试也没有错误地通过。
Try actual column names in your SQL query.在 SQL 查询中尝试实际的列名。 Instead of this:
而不是这个:
SELECT * FROM PERSON ORDER BY EMAIL
Try this:尝试这个:
SELECT PERSONID, EMAIL, PASSWORD,... FROM PERSON ORDER BY EMAIL
You should get the essence from your error outputs.您应该从错误输出中获得精髓。
It relates lambda code inside a constructor INIT, no such method getPersons它与构造函数 INIT 中的 lambda 代码相关,没有这样的方法 getPersons
WITH the problem the code should have an exception wrapped around or added onto the constructor declaration start, supposedly at least for the get request code eg throws ServletException and UnavailableException有问题的代码应该有一个异常包装或添加到构造函数声明开始,据说至少对于获取请求代码,例如 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();
});
The following references an odd action you take of getting all the persons onto a Collection object with getPersons method, but you do nothing with it except return it i presume as " ctx " and unfortunately you did not actually say the type of object ctx is.以下引用了一个奇怪的操作,即您使用 getPersons 方法将所有人员放到 Collection object 上,但除了将其返回我假定为“ ctx ”之外,您什么也不做,不幸的是,您实际上并没有说 object ctx 的类型是。
@Override
@SqlQuery("SELECT * FROM PERSON ORDER BY EMAIL")
@RegisterBeanMapper(Person.class)
public Collection<Person> getPersons();
Somehow ALL the required constructor parameters for Person class are sent in a post, but in get no Person class is made in the code which i find odd that it did not continue to throw errors whether you gave it a no-arguments constructor as an abstract class has, but wonder if it is treated as an abstract class, the more normal way is to make a DTO Data Transfer Object template and不知何故,Person class 所需的所有构造函数参数都在帖子中发送,但在代码中没有生成 Person class ,我觉得奇怪的是,无论您是否给它一个无参数构造函数作为抽象,它都没有继续抛出错误class 有,但是想知道是不是把它当作抽象的 class 处理,比较正常的方法是做一个 DTO 数据传输 Object 模板和
entity in between the DAO Data Access Object class with interfaces to call through. DAO 数据访问 Object class 之间的实体,具有调用接口。 Moreover, the getPersons collection does not appear to have any use, so why the massive query retrieval.
而且,getPersons 集合似乎没有任何用处,何必海量查询检索。
I have found the issue,我发现了问题,
I the constructor in my Domain class seemed to be the error, I fixed the error by adding an empty constructor in my Person.class above the current one我的域 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;
}
Now it works fine.现在它工作正常。 If anyone has an explanation for why this is I'd love to know:)
如果有人解释为什么会这样,我很想知道:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.