简体   繁体   English

Jersey RESTful Service 500错误(请求为空)

[英]Jersey RESTful Service 500 Error (request is null)

I'm a new in REST services and I want to make test with Jersey Test Framework. 我是REST服务的新手,我想使用Jersey测试框架进行测试。 Configuration seems to be ok (not null) but debugger has shown that the request is null. 配置似乎可以(不是null),但是调试器显示请求为null。 Changing paths in target() -method gave nothing. 更改target()方法中的路径没有任何效果。 Found many answers but they did not help. 找到了很多答案,但没有帮助。 So why request can be null? 那么,为什么请求可以为空?

TestReportResource.java TestReportResource.java

public class TestReportResource extends JerseyTest {
    private ETS tmEts;
    private ETS suEts;
    private ReportService mockReportService;
    private ReportResource reportResource;
    private ReportResource reportResourceNew;
    private MapperFacade mapper;
    private ReportServiceJerseyMockTest mockReportServiceJersey;

    @Before
    public void init() {
        this.tmEts = TestUtils.loginAs(TestUtils.PURE_TM, TestUtils.PASSWORD_COMMON);
        this.suEts = TestUtils.loginAs(TestUtils.PURE_SU, TestUtils.PASSWORD_COMMON);
        this.mapper = EntityMapperFactory.getMapper();

        this.mockReportService = mock(ReportService.class);
        this.reportResource = new ReportResource(this.mockReportService, this.mapper);
    }


    @Override
    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
        return new JdkHttpServerTestContainerFactory();
    }

    @Override
    protected Application configure() {
        this.mockReportServiceJersey = new ReportServiceJerseyMockTest(); **//fields are here, because init() initiates later than configure()**
        this.reportResource = new ReportResource(this.mockReportServiceJersey, this.mapper);

        ResourceConfig config = new ResourceConfig(ReportResource.class);

        AbstractBinder binder = new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(ReportServiceJerseyMockTest.class).to(IReportService.class);
            }
        };
        config.register(binder);
        return config;
    }


    @Test
    public void testGetProjectManagersRestJersey() {

        List<ManagerUserEntity> testList = (List<ManagerUserEntity>) new ReportServiceJerseyMockTest().getProjectManagers(tmEts, "login");

        ManagerUserEntity managerUserEntity = target("/reports/project-managers").request().get(ManagerUserEntity.class); **// request equals to null**

        assertEquals(testList, mapper.mapAsList(List of entities received from ReportResource.getProjectManagers, ManagerUserEntity.class));
        (not ended)
    }

}

ReportResource.java - the resource class which is under testing ReportResource.java-正在测试的资源类

@Path("/reports/")
public class ReportResource {
    @Inject
    private IReportService reportService;
    private MapperFacade mapper;


    @GET
    @Path("project-managers")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<ManagerUserDTO> getProjectManagers(@Context  HttpServletRequest request, 
                                 @DefaultValue("All") 
                                 @QueryParam("lmLogin") String lmLogin) {

        ETS ets = (ETS) request.getAttribute("ets"); **// request equals null**

        Collection<ManagerUserEntity> entities = this.reportService.getProjectManagers(ets, lmLogin);

        return mapper.mapAsList(entities, ManagerUserDTO.class);
    }

}

StackTrace 堆栈跟踪

javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
    at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1020)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:816)
    at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92)
    at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:700)
    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:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:696)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316)
    at test.rest.TestReportResource.testGetProjectManagersRestJersey(TestReportResource.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

So there are a couple problems 所以有几个问题

First, JerseyTest already has a @Before method where it calls you configure method create the Jersey application. 首先, JerseyTest已经有一个@Before方法 ,它在其中调用您的configure方法创建Jersey应用程序。 This @Before is called before your @Before , so any application configuration should not be done in this method. @Before之前称为@Before ,因此任何应用程序配置不应该在这个方法来完成。 It is OK to use for things used in your @Test methods. 可以将@Test方法中使用的东西使用。

Second, you have not configured your MapperFacade . 其次,您尚未配置MapperFacade So your resource class never gets it. 因此,您的资源类永远都不会得到它。 I imagine this is the cause of the 500 (the main cause being an NPE). 我想这是500的原因(主要原因是NPE)。 So do two things 所以做两件事

  1. Initialize the MapperFacade in the configure method of the JerseyTest , then configure it in the configure method of the AbstractBinder JerseyTestconfigure方法中初始化MapperFacade ,然后在AbstractBinderconfigure方法中对其进行configure

     final MapperFacade mapper = EntityMapper.getMapper(); AbstractBinder binder = new AbstractBinder() { @Override protected void configure() { ... bind(mapper).to(MapperFacade.class); } }; 
  2. Add the @Inject annotation to it in the resource class 在资源类中向其添加@Inject批注

      public class ReportResource { @Inject private MapperFacade mapper; 

As an aside, when getting a 500 Server Error, and there is no stack trace (for the real exception), often is is swallowed by the framework and converted to a framework specific exception, which isn't much help, like in your case. 顺便说一句,当出现500服务器错误,并且没有堆栈跟踪(针对真正的异常)时,通常会被框架吞噬并转换为特定于框架的异常,这对您没有太大帮助,就像您遇到的情况一样。 In situations like this, I just add a debugging ExceptionMapper , that prints the stack trace. 在这种情况下,我只需要添加一个调试ExceptionMapper打印堆栈跟踪。 This should give you some information 这应该给你一些信息

@Provider
public static class DebugMapper implements ExceptionMapper<Throwable> {
    @Overrride
    public Response toResponse(Throwable e) {
        e.printStackTrace();
        return Response.serverError().build();
    }
}

@Override
public Application configure() {
    ResourceConfig config = new ResourceConfig(..);
    config.register(DebugMapper.class);
}

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

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