2016-05-31 66 views
0

我正在構建一個基於MVC體系結構的webapp。來自JSP頁面的表單數據被轉發給委託給Controller的Dispatcher Servlet。我已經設法注入一個控制器,它工作得很好。嘗試使用映射注入控制器時發生NullPointerException

對於多個控制器我在servlet中創建了一個映射處理程序,它通過讀取屬性文件將請求映射到相關控制器。我已經注入了映射處理程序,但我仍然收到NullPointerException

一個額外的ControllerBundle只是將控制器和方法名稱抽象爲一個對象。我使用tomee webprofile 1.7.4

DispatcherServlet.java:

package a1; 

// imports 

public class DispatcherServlet extends HttpServlet { 

    @Inject 
    @Named("MappingHandler") 
    private MappingHandler MAPPING_HANDLER; 

    // ** Single controller ** 
    // @Inject 
    // @Named("customerController") 
    // private CustomerController controller; 

    @Override 
    public void init() throws ServletException { 
     MAPPING_HANDLER.generate(); 
    } 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     try { 
      String pathInfo = req.getPathInfo(); 
      Controller controller = MAPPING_HANDLER.getController(pathInfo); 
      String methodName = MAPPING_HANDLER.getMethod(pathInfo); 
      Method method = controller.getClass().getDeclaredMethod(methodName, HttpServletRequest.class); 

      method.setAccessible(true); 
      method.invoke(controller, req); 
      req.getRequestDispatcher("/results.jsp").forward(req, resp); 

      // ** Single controller ** 
      // String methodName = "addCustomer"; 
      // Method method = controller.getClass().getDeclaredMethod(methodName, HttpServletRequest.class); 
      // 
      // method.setAccessible(true); 
      // method.invoke(controller, req); 
      // req.getRequestDispatcher("/success.jsp").forward(req, resp); 

     } catch (SecurityException | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

MappingHandler.java:

package a1; 

// imports 

@Named("MappingHandler") 
public class MappingHandler { 

    private static final Map<String, ControllerBundle> CONTROLLER_BUNDLE_MAP = new HashMap<>(); 

    private static final String PACK = "a1."; 

    void generate() { 
     try { 
      Properties props = new Properties(); 
      InputStream is1 = this.getClass().getClassLoader().getResourceAsStream("mappings_h6.properties"); 
      props.load(is1); 

      Enumeration e = props.propertyNames(); 
      while (e.hasMoreElements()) { 
       String left = (String) e.nextElement(); 
       String right = props.getProperty(left); 

       // ControllerBundle: abstraction containing both the Controller and the name of the method 
       ControllerBundle controllerBundle = new ControllerBundle(right, PACK); 
       CONTROLLER_BUNDLE_MAP.put(left, controllerBundle); 
      } 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    Controller getController(String pathInfo) { 
     ControllerBundle controllerBundle = CONTROLLER_BUNDLE_MAP.get(pathInfo); 
     Controller controller = controllerBundle.getController(); 
     return controller; 
    } 

    String getMethod(String pathInfo) { 
     ControllerBundle controllerEntity1 = CONTROLLER_BUNDLE_MAP.get(pathInfo); 
     String methodName = controllerEntity1.getMethodName(); 
     return methodName; 
    } 
} 

ControllerBundle.java:

package a1; 

// imports 

public class ControllerBundle { 

    private Controller controller; 
    private String methodName; 
    private static final Map<String, Controller> CONTROLLER_MAP = new HashMap<>(); 

    public ControllerBundle(String value, String pack) { 
     String[] valueSplit = value.split("#"); 

     String controllerName = valueSplit[0]; 
     Controller controller = findController(pack, controllerName); 
     String methodName = valueSplit[1]; 

     this.controller = controller; 
     this.methodName = methodName; 
    } 

    // Keep only one copy of every controller 
    private static Controller findController(String pack, String controllerName) { 
     try { 

      Class currentControllerClass = Class.forName(pack + controllerName); 
      for (String s : CONTROLLER_MAP.keySet()) { 
       Class existingControllerClass = CONTROLLER_MAP.get(s).getClass(); 
       if (currentControllerClass == existingControllerClass) { 
        return (Controller) existingControllerClass.newInstance(); 
       } 
      } 

      Controller currentController = (Controller) currentControllerClass.newInstance(); 
      CONTROLLER_MAP.put(controllerName, currentController); 
      return currentController; 

     } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    Controller getController() { 
     return controller; 
    } 

    String getMethodName() { 
     return methodName; 
    } 
} 

mappings_h6.properties:

/customer/add=CustomerController#addCustomer 
/customer/update=CustomerController#updateCustomer 
/account/create=AccountController#createAccount 
/account/freeze=AccountController#freezeAccount 

的beans.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
     http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
     bean-discovery-mode="all"> 
</beans> 

回答

-1

你有在WEB-INF或WEB-INF /班/ META-INF一個beans.xml文件?否則,tomee 1.x CDI未激活。

+0

是的,我剛剛添加了beans.xml – Irfaan

+0

您添加的片段是EE 7 beans.xml,因此對於TomEE 1無效(對TomEE 7有效)。只是嘗試「」 –

相關問題