java - 用 dropwizard 编写的简单待办事项应用程序后端 api 会产生 500 错误

标签 java maven dropwizard

就此而言,我是 dropwizard 或 java 的新手。我正在尝试使用 dropwizard 创建一个简单的 todo 后端 api。我已经编写了一些代码,但是当我在 postman 中测试它时收到 500 错误。下面是我的代码:

表示类:

package com.todo.api.db;

import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;

import javax.persistence.*;

@Entity
@Table(name = "todo")
@NamedQueries({
        @NamedQuery(name = "com.todo.api.db.TodoModel.getAll", query = "select t from TodoModel t"),
        @NamedQuery(name = "com.todo.api.db.TodoModel.getById", query = "select t from TodoModel t where t.id = :id")
})
public class TodoModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "task")
    private String task;

    @Column(name = "completed")
    private Boolean completed;

    @Column(name = "created_at")
    private String created_at;

    public TodoModel(String task, Boolean completed, String created_at) {
        this.task = task;
        this.completed = completed;
        this.created_at = created_at;
    }

    public String getTask(){
        return task;
    }

    public void setTask(String task){
        this.task = task;
    }

    public Boolean getCompleted(){
        return completed;
    }

    public void setCompleted(Boolean completed){
        this.completed = completed;
    }

    public String getCreated_at(){
        return created_at;
    }

    public void setCreated_at(String created_at){
        this.created_at = created_at;
    }

}

DAO 类:

package com.todo.api.db;

import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.SessionFactory;

import java.util.List;

public class TodoDAO extends AbstractDAO<TodoModel> {
    public TodoDAO(SessionFactory factory) {
        super(factory);
    }

    public List<TodoModel> getAll(){
        return list(
                namedQuery("com.todo.api.db.TodoModel.getAll")
        );
    }

    public List<TodoModel> getById(){
        return list(
                namedQuery("com.todo.api.db.TodoModel.getById")
        );
    }
}

资源类别:

package com.todo.api.resources;

import com.todo.api.db.TodoDAO;
import com.todo.api.db.TodoModel;
import io.dropwizard.jersey.params.LongParam;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/api")
@Produces(MediaType.APPLICATION_JSON)
public class HelloResource {

    private TodoDAO todoDao;

    public HelloResource(TodoDAO todoDao){
        this.todoDao = todoDao;
    }
    @GET
    public List<TodoModel> findAll(){
        return (todoDao.getAll());
    }

    @GET
    @Path("/{id}")
    public List<TodoModel> findId(@PathParam("id") LongParam id){
        return todoDao.getById();
    }

    @POST
    public List<TodoModel> postAll(@PathParam("id") LongParam id){
        return todoDao.getById();
    }


}

我收到的错误:

ERROR [2019-04-23 08:44:08,864] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: b49aa01dcd315c8d
! org.hibernate.HibernateException: No session currently bound to execution context
! at org.hibernate.context.internal.ManagedSessionContext.currentSession(ManagedSessionContext.java:58)
! at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:464)
! at io.dropwizard.hibernate.AbstractDAO.currentSession(AbstractDAO.java:44)
! at io.dropwizard.hibernate.AbstractDAO.namedQuery(AbstractDAO.java:76)
! at com.todo.api.db.TodoDAO.getAll(TodoDAO.java:15)
! at com.todo.api.resources.HelloResource.findAll(HelloResource.java:22)
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
! at java.lang.reflect.Method.invoke(Method.java:498)
! at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
! at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
! at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
! at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
! at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
! at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
! at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
! at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
! at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
! at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623)
! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:35)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:45)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:39)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
! at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
! at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
! at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
! at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
! at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:239)
! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:52)
! at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:753)
! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:67)
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56)
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:174)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
! at org.eclipse.jetty.server.Server.handle(Server.java:502)
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
! at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
! at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
! at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
! at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
! at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
! at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
! at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
! at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
! at java.lang.Thread.run(Thread.java:748)
0:0:0:0:0:0:0:1 - - [23/Apr/2019:08:44:08 +0000] "GET /api/ HTTP/1.1" 500 110 "-" "PostmanRuntime/7.11.0" 4

有人可以修复代码以便 API 正常工作吗?提前致谢!

编辑1: 我似乎通过向资源类中的请求方法添加 @unitofWork 注释来解决了上述错误。但我现在有一个新问题。当我尝试从 postman 处执行 GET 或 POST 请求时,我收到一个空列表“[]”。为什么我会得到这个?我该如何解决这个问题,以便获得 JSON 列表而不仅仅是空列表?

编辑2: 我已经添加了答案并记录了迄今为止的进展。我仍在尝试使 POST 请求起作用。任何帮助都会很棒..

最佳答案

所以我对我的代码进行了以下更改..

我的模型/表示类:向其中添加了一个空构造函数。

package com.todo.api.db;

import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;

import javax.persistence.*;

@Entity
@Table(name = "todo")
@NamedQueries({
        @NamedQuery(name = "com.todo.api.db.TodoModel.getAll", query = "select t from TodoModel t"),
        @NamedQuery(name = "com.todo.api.db.TodoModel.getById", query = "select t from TodoModel t where t.id = :id")
})
public class TodoModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "task")
    private String task;

    @Column(name = "completed")
    private Boolean completed;

    @Column(name = "created_at")
    private String created_at;

    public TodoModel(){
    }

    public TodoModel(String task, Boolean completed, String created_at) {
        this.task = task;
        this.completed = completed;
        this.created_at = created_at;
    }

    public String getTask(){
        return task;
    }

    public void setTask(String task){
        this.task = task;
    }

    public Boolean getCompleted(){
        return completed;
    }

    public void setCompleted(Boolean completed){
        this.completed = completed;
    }

    public String getCreated_at(){
        return created_at;
    }

    public void setCreated_at(String created_at){
        this.created_at = created_at;
    }

}

对 DAO 类进行了以下更改:

package com.todo.api.db;

import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

import java.util.List;

public class TodoDAO extends AbstractDAO<TodoModel> {
    public TodoDAO(SessionFactory factory) {
        super(factory);
    }

    public TodoModel create(TodoModel todoModel){
        return persist(todoModel);
    }

    public List<TodoModel> getAll(){
        final Criteria c = criteria();
        List results = c.list();
        return results;
    }
    public TodoModel getById(Long id){
        final Criteria c = criteria();
        c.add(Restrictions.eq("id", id));

        final List<TodoModel> todoModels = c.list();

        return todoModels.get(0);

    }
}

并对资源类进行以下更改:

package com.todo.api.resources;

import com.todo.api.db.TodoDAO;
import com.todo.api.db.TodoModel;
import io.dropwizard.hibernate.UnitOfWork;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/api")
@Produces(MediaType.APPLICATION_JSON)
public class HelloResource {

    private TodoDAO todoDao;

    public HelloResource(TodoDAO todoDao){
        this.todoDao = todoDao;
    }

    @GET
    @UnitOfWork
    public List<TodoModel> findAll(){
        return (todoDao.getAll());
    }

    @GET
    @UnitOfWork
    @Path("/{id}")
    public TodoModel findId(@PathParam("id") Long id)
    {
        return todoDao.getById(id);

    }

    @POST
    @UnitOfWork
    public TodoModel post(TodoModel todoModel)
    {

        return todoDao.create(todoModel);
    }


}

关于java - 用 dropwizard 编写的简单待办事项应用程序后端 api 会产生 500 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55795110/

相关文章:

java - 实现不应调用的派生方法的最佳实践

Treeview、TreeItem/TreeCell 上的 JavaFX 自动换行

java - 添加多个字节数组

maven - 运行单元测试是否需要 maven surefire 插件?

debugging - 在 Netbeans 上调试 gradle 应用程序

grails - 带有 Dropwizard 指标的 grails 中的注释不起作用

java - Java 中的预处理器变量

maven - 是否有版本 0.12.1.20110112-1712 的 Maven 插件?

java - 有没有办法从文件中加载 Maven Surefire 插件排除列表?

log4j - Dropwizard 中默认记录到文件和控制台是否使用 AsyncAppender?