NullPointer异常究竟在哪里?

时间:2018-03-16 17:59:19

标签: mongodb spring-boot testing nullpointerexception

我正在使用Spring和MongoDb测试API Rest资源。 这是"链"从资源到文档的关系:

资源:

@RestController
@RequestMapping(CustomerResource.CUSTOMERS)
public class CustomerResource {

public static final String CUSTOMERS = "/customers";

public static final String CUSTOMER_ID = "/{id}";

@Autowired
private CustomerController customerController;

@PostMapping
public void createCustomer(@RequestBody CustomerDto customerDto) {
    this.customerController.createCustomer(customerDto);
}

...

}

控制器:

@Controller
public class CustomerController {

private CustomerRepository customerRepository;


...

public void createCustomer(CustomerDto customerDto) {
    Customer customer = new Customer(customerDto.getName(),
    customerDto.getAddress());
    this.customerRepository.save(customer);
}

...
}

dto:

public class CustomerDto {


private String name;

private String address;

private Date date;

public CustomerDto (String name, String address) {
    this.name = name;
    this.address = address;
}

public CustomerDto() {
}

...(getters & setters & toString())...
}

存储库:

public interface CustomerRepository extends MongoRepository<Customer, String> {

public List<Customer> findByName(String name);

public Customer findById(String id);

public List<Customer> findAll();

@Query("{$and:[{'name':?0},{'address':?1}]}")
Customer findByNameAndAddress(String name, String address);

}

文件:

@Document
public class Customer {

@Id
private String id;

private String name;

private String address;

private Date date;

public Customer (String name, String address) {
    this();
    this.name = name;
    this.address = address;
    this.date = new Date();
}

public Customer() {
}

public String getId() {
    return id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public Date getDate() {
    return date;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Customer other = (Customer) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

@Override
public String toString() {
    return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", date=" + date + "]";
}

}

但是在运行测试时,我得到了NullPointer异常,并且我不明白过程的哪一点是错误。

资源测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = "classpath:test.properties")
public class CustomerResourceFunctionalTesting {

 @Rule
 public ExpectedException thrown = ExpectedException.none();

 @Autowired
 private RestService restService;

 private CustomerDto customerDto;

 @Before
    public void before() {
        this.customerDto = new CustomerDto("Mark", "Washington");
    }

 @Test
    public void testCreateCustomer() {
        restService.restBuilder().path(CustomerResource.CUSTOMERS).body(this.customerDto).post().build();
    }

}

我认为这可能与未明确声明id字段有关,但是因为它将被&#34;实例化&#34;通过@Id注释,我不认为存在问题。

这是追踪:

org.springframework.web.client.HttpServerErrorException: 500 
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:708)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:661)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:636)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:557)
at account.persistence.resources.RestBuilder.build(RestBuilder.java:191)
at account.persistence.resources.CustomerResourceFunctionalTesting.testCreateCustomer(CustomerResourceFunctionalTesting.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

但我认为控制台日志会更有用:

java.lang.NullPointerException: null
at account.persistence.controllers.CustomerController.createCustomer(CustomerController.java:36) ~[classes/:na]
at account.persistence.resources.CustomerResource.createCustomer(CustomerResource.java:36) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.27.jar:8.5.27]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.27.jar:8.5.27]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_144]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.27.jar:8.5.27]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_144]

修改

这是RestBuilder(在resoure测试的同一个文件夹中):

public class RestBuilder<T> {

private static final String SERVER_URI_DEFAULT = "http://localhost";

private static final int PORT_DEFAULT = 8080;

private RestTemplate restTemplate = new RestTemplate();

private String serverUri;

private int port;

private String path;

private List<Object> expandList;

private Map<String, String> headerValues;

private List<MediaType> mediaTytes;

private String authorization = null;

private Object body = null;

private MultiValueMap<String, String> params;

private Class<T> clazz;

private HttpMethod method;

private boolean log;

public RestBuilder(String serverUri, int port) {
    restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); // org.apache.httpcomponents.httpclient
    this.serverUri = serverUri;
    this.port = port;
    this.path = "";
    this.expandList = new ArrayList<>();
    this.headerValues = new HashMap<>();
    this.mediaTytes = new ArrayList<>();
    this.params = new HttpHeaders();
    this.log = false;
}

public RestBuilder() {
    this(SERVER_URI_DEFAULT, PORT_DEFAULT);
}

public RestBuilder(int port) {
    this(SERVER_URI_DEFAULT, port);
}

public RestBuilder(String serverUri) {
    this(serverUri, PORT_DEFAULT);
}

public RestBuilder<T> clazz(Class<T> clazz) {
    this.clazz = clazz;
    return this;
}

public RestBuilder<T> port(int port) {
    this.port = port;
    return this;
}

public RestBuilder<T> serverUri(String serverUri) {
    this.serverUri = serverUri;
    return this;
}

public RestBuilder<T> path(String path) {
    this.path = this.path + path;
    return this;
}

public RestBuilder<T> expand(Object... values) {
    for (Object value : values) {
        this.expandList.add(value);
    }
    return this;
}

public RestBuilder<T> basicAuth(String token) {
    return basicAuth(token, "");
}

public RestBuilder<T> basicAuth(String nick, String pass) {
    String auth = nick + ":" + pass;
    String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
    String authHeader = "Basic " + encodedAuth;
    this.authorization = authHeader;
    return this;
}

public RestBuilder<T> param(String key, String value) {
    this.params.add(key, value);
    return this;
}

public RestBuilder<T> header(String key, String value) {
    this.headerValues.put(key, value);
    return this;
}

public RestBuilder<T> accept(MediaType mediaType) {
    if (this.mediaTytes.isEmpty()) {
        this.mediaTytes.add(MediaType.APPLICATION_JSON);
    }
    this.mediaTytes.add(mediaType);
    return this;
}

public RestBuilder<T> body(Object body) {
    this.body = body;
    return this;
}

public RestBuilder<T> notError() {
    restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
        protected boolean hasError(HttpStatus statusCode) {
            return false;
        }
    });
    return this;
}

private HttpHeaders headers() {
    HttpHeaders headers = new HttpHeaders();
    for (String key : headerValues.keySet()) {
        headers.set(key, headerValues.get(key));
    }
    if (authorization != null) {
        headers.set("Authorization", authorization);
    }
    if (!this.mediaTytes.isEmpty()) {
        headers.setAccept(this.mediaTytes);
    }
    return headers;
}

private URI uri() {
    UriComponents uriComponents;
    if (params.isEmpty()) {
        uriComponents = UriComponentsBuilder.fromHttpUrl(serverUri + ":" + port + path).build();
    } else {
        uriComponents = UriComponentsBuilder.fromHttpUrl(serverUri + ":" + port + path).queryParams(params).build();
    }
    if (!expandList.isEmpty()) {
        uriComponents = uriComponents.expand(expandList.toArray());
    }
    return uriComponents.encode().toUri();

}

public RestBuilder<T> log() {
    this.log = true;
    return this;
}

public T build() {
    ResponseEntity<T> response;
    if (log) {
        Logger.getLogger(this.getClass()).info(method + " " + this.path + this.headers() + "{" + this.body + "}");
    }
    if (body != null && !method.equals(HttpMethod.GET)) {
        response = restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(body, this.headers()), clazz);
        if (log) {
            Logger.getLogger(this.getClass()).info(response.getStatusCode() + "==" + response.getHeaders());
        }
        return response.getBody();
    } else {
        response = restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(this.headers()), clazz);
        if (log) {
            Logger.getLogger(this.getClass()).info(response.getStatusCode() + "==" + response.getHeaders());
        }
        return response.getBody();
    }
}

public RestBuilder<T> post() {
    this.method = HttpMethod.POST;
    return this;
}

public RestBuilder<T> get() {
    this.method = HttpMethod.GET;
    return this;
}

public RestBuilder<T> put() {
    this.method = HttpMethod.PUT;
    return this;
}

public RestBuilder<T> patch() {
    this.method = HttpMethod.PATCH;
    return this;
}

public RestBuilder<T> delete() {
    this.method = HttpMethod.DELETE;
    return this;
}

}

RestService(与RestBuilder在同一个文件夹中):

@Service
public class RestService {

@Autowired
private Environment environment;

@Value("${server.contextPath}")
private String contextPath;

private int port() {
    return Integer.parseInt(environment.getProperty("local.server.port"));
}

public <T> RestBuilder<T> restBuilder(RestBuilder<T> restBuilder) {
    restBuilder.port(this.port());
    restBuilder.path(contextPath);
    return restBuilder;
}

public RestBuilder<Object> restBuilder() {
    RestBuilder<Object> restBuilder = new RestBuilder<>(this.port());
    restBuilder.path(contextPath);
    return restBuilder;
}

}

编辑2

作为替代方案,我尝试了另一种方法,因为我在Resource Access Exception中通过不使用RestService而不是修改测试和restbuilder来解释,但是在访问资源时我得到了一个异常。 / p>

1 个答案:

答案 0 :(得分:0)

尝试在@Autowired

上添加CustomerController注释
@Autowired
private CustomerRepository customerRepository;

可能原因NullPointerException是存储库没有正确注入。