Java 并行请求的NullPointer异常

Java 并行请求的NullPointer异常,java,multithreading,spring-boot,thread-safety,Java,Multithreading,Spring Boot,Thread Safety,有人能告诉我这个代码有什么问题吗 我得到空指针异常,我假设是因为多个请求 @Service public class GernericMockingServiceImpl implements GenericMockingService { private static final Logger LOG = LoggerFactory.getLogger(GernericMockingServiceImpl.class); @Override public Strin

有人能告诉我这个代码有什么问题吗

我得到空指针异常,我假设是因为多个请求

@Service
public class GernericMockingServiceImpl implements GenericMockingService {

    private static final Logger LOG = LoggerFactory.getLogger(GernericMockingServiceImpl.class);

    @Override
    public String getJsonResponse(GenericMockingForm genericMockingForm, String requestURI) throws Exception {
        LOG.info("printing requestURI : "+requestURI);
        String path = new URI(requestURI).getPath();
        //resolves to a folder name in src/main/resources
        String folderName = path.substring(path.lastIndexOf('/') + 1);
        LOG.info("printing folderName : " + folderName);
        String jsonResponse = null;
        StringBuilder sb = new StringBuilder();

        //check if the request body has prodcut id's which means that the request is for products else check for sku's which means that the request is for price or stock
        if(!Objects.isNull(genericMockingForm.getProductIds()) && !genericMockingForm.getProductIds().isEmpty()){
            //currently it iterates over all the product id's/sku's in the request and appends the content of all the id's
            //TODO: the content of the file is not exactly how we want it to be for multiple ids' But for the single id it just works.
            // TODO: Needs to be refactored later when we handle multiple id's in request
            for(String productId : genericMockingForm.getProductIds()){
                jsonResponse = getJson(folderName, productId, sb);
            }
        }else{
            for (String sku : genericMockingForm.getSkus()) {
                jsonResponse = getJson(folderName, sku, sb);
            }
        }
        LOG.info("printing jsonResponse : " + jsonResponse);
        return jsonResponse;
    }

    private String getJson(String folderName, String id, StringBuilder sb) throws Exception {
        String responseJson = null;
        String filePath = "data" + File.separator + folderName + File.separator + id + ".json";
        LOG.info("printing filePath : " + filePath);
        LOG.info("printing id : " + id);
        File f = new File(filePath);
        if(f.exists()){
            try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
                LOG.info("printing inputStream : " + inputStream);
                if (inputStream != null) {
                    responseJson = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
                }
                if (responseJson == null || responseJson.isEmpty()) {
                    LOG.info("json response is null : ");
                    throw new JsonNotFoundException(Constant.JSON_NOT_FOUND);   
                }
                sb.append(responseJson);
            } catch (IOException e) {
                LOG.info("IO exception : ");
                throw new IOException(e);
            } catch (Exception e) {
                LOG.info(" exception : ");
                throw new Exception(e);
            }
        }
        else{
            LOG.info("file doesnt exists : " + filePath);
        }
        return sb.toString();
    }
}
**我有3个并行请求访问一个包含3个不同文件的文件夹,并尝试读取这些文件

这是我的堆栈跟踪**

  2019-03-05 17:30:29.335  INFO 82 --- [nio-8080-exec-1] c.k.m.controller.ProductController       : Received request for Mocking Controller
    2019-03-05 17:30:29.335  INFO 82 --- [nio-8080-exec-3] c.k.m.controller.ProductController       : Received request for Mocking Controller
    2019-03-05 17:30:29.335  INFO 82 --- [nio-8080-exec-2] c.k.m.controller.ProductController       : Received request for Mocking Controller
    2019-03-05 17:30:29.336  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : printing requestURI : /mocking/api/stocks
    2019-03-05 17:30:29.336  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : printing requestURI : /mocking/get-products
    2019-03-05 17:30:29.337  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : printing folderName : get-products
    2019-03-05 17:30:29.338  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : printing filePath : data/get-products/1610-17637-319.json
    2019-03-05 17:30:29.338  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : printing id : 1610-17637-319
    2019-03-05 17:30:29.338  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : file doesnt exists : data/get-products/1610-17637-319.json
    2019-03-05 17:30:29.338  INFO 82 --- [nio-8080-exec-3] c.k.m.s.impl.GernericMockingServiceImpl  : printing jsonResponse : 
    2019-03-05 17:30:29.336  INFO 82 --- [nio-8080-exec-1] c.k.m.s.impl.GernericMockingServiceImpl  : printing requestURI : /mocking/api/prices
    2019-03-05 17:30:29.338  INFO 82 --- [nio-8080-exec-1] c.k.m.s.impl.GernericMockingServiceImpl  : printing folderName : prices
    2019-03-05 17:30:29.337  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : printing folderName : stocks
    2019-03-05 17:30:29.343  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : printing filePath : data/stocks/1610-17637.json
    2019-03-05 17:30:29.343  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : printing id : 1610-17637
    2019-03-05 17:30:29.343  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : file doesnt exists : data/stocks/1610-17637.json
    2019-03-05 17:30:29.343  INFO 82 --- [nio-8080-exec-2] c.k.m.s.impl.GernericMockingServiceImpl  : printing jsonResponse : 
    2019-03-05 17:30:29.354 ERROR 82 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

    java.lang.NullPointerException: null
        at com.kfz24.mockingservice.service.impl.GernericMockingServiceImpl.getJsonResponse(GernericMockingServiceImpl.java:45) ~[classes/:na]
        at com.kfz24.mockingservice.controller.GenericMockingController.processRequest(GenericMockingController.java:32) ~[classes/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        **at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.4.RELEASE.jar:5.1.4.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.4.RELEASE.jar:5.1.4.RELEASE]**
我得到空指针异常,我假设是因为多个请求

@Service
public class GernericMockingServiceImpl implements GenericMockingService {

    private static final Logger LOG = LoggerFactory.getLogger(GernericMockingServiceImpl.class);

    @Override
    public String getJsonResponse(GenericMockingForm genericMockingForm, String requestURI) throws Exception {
        LOG.info("printing requestURI : "+requestURI);
        String path = new URI(requestURI).getPath();
        //resolves to a folder name in src/main/resources
        String folderName = path.substring(path.lastIndexOf('/') + 1);
        LOG.info("printing folderName : " + folderName);
        String jsonResponse = null;
        StringBuilder sb = new StringBuilder();

        //check if the request body has prodcut id's which means that the request is for products else check for sku's which means that the request is for price or stock
        if(!Objects.isNull(genericMockingForm.getProductIds()) && !genericMockingForm.getProductIds().isEmpty()){
            //currently it iterates over all the product id's/sku's in the request and appends the content of all the id's
            //TODO: the content of the file is not exactly how we want it to be for multiple ids' But for the single id it just works.
            // TODO: Needs to be refactored later when we handle multiple id's in request
            for(String productId : genericMockingForm.getProductIds()){
                jsonResponse = getJson(folderName, productId, sb);
            }
        }else{
            for (String sku : genericMockingForm.getSkus()) {
                jsonResponse = getJson(folderName, sku, sb);
            }
        }
        LOG.info("printing jsonResponse : " + jsonResponse);
        return jsonResponse;
    }

    private String getJson(String folderName, String id, StringBuilder sb) throws Exception {
        String responseJson = null;
        String filePath = "data" + File.separator + folderName + File.separator + id + ".json";
        LOG.info("printing filePath : " + filePath);
        LOG.info("printing id : " + id);
        File f = new File(filePath);
        if(f.exists()){
            try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
                LOG.info("printing inputStream : " + inputStream);
                if (inputStream != null) {
                    responseJson = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
                }
                if (responseJson == null || responseJson.isEmpty()) {
                    LOG.info("json response is null : ");
                    throw new JsonNotFoundException(Constant.JSON_NOT_FOUND);   
                }
                sb.append(responseJson);
            } catch (IOException e) {
                LOG.info("IO exception : ");
                throw new IOException(e);
            } catch (Exception e) {
                LOG.info(" exception : ");
                throw new Exception(e);
            }
        }
        else{
            LOG.info("file doesnt exists : " + filePath);
        }
        return sb.toString();
    }
}
我认为你的假设是错误的

[来自注释:空值是]这一行
for(字符串sku:genericMockingForm.getSkus()){

这似乎表明
genericMockingForm.getSkus()
正在返回
null
,因为这里使用的唯一其他对象是上面测试的
genericMockingForm

您应该对该表单测试进行相同的空检查:

 if (!Objects.isNull(genericMockingForm.getSkus())) ...

如果它们都是
null
,那么你应该抛出某种用法错误。

你能告诉我们异常发生的那一行吗……或者你能告诉我们代码中那一行是
GernericMockingServiceImpl.java:45
。这一行是(字符串sku:genericMockingForm.getSkus()){基本上第一个请求检查Objects.isNull(genericMockingForm.getProductIds())&!genericMockingForm.getProductIds().isEmpty(),然后另一个请求检查else块并行,并且这不会只发生在单个请求中?它基本上看起来像
getSkus()返回的值
为空。这将使for循环失败。genericMockingForm可以在任何时间点具有productId或sku,但不能同时具有这两个