Vaadin7 Navigation 中的 NPE 使用我自己的 ViewProvider 实现。

NPE in Vaadin7 Navigation with my own ViewProvider implementation.

我尝试使用 Navigator 创建一个 vaadin7 应用程序。 我有自己的 ViewProvider 实现。

这里是 UI class 的相关部分:

 @Override
protected void init(VaadinRequest request) {
    layout = new VerticalLayout();
    layout.setSizeFull();

    setContent(layout);

    navigator = new Navigator(this, layout);
    mainView = new MainView(navigator);
    navigator.addView("", mainView);

    ViewProviderImpl viewProviderImpl = new ViewProviderImpl(mainView);
    navigator.addProvider(viewProviderImpl);
}

这里是主视图:(这是默认应该显示的那个。目前它只包含两个按钮。如果点击按钮,导航器应该将他带到其他视图之一)

 public MainView(Navigator navigator) {

    this.setSizeFull();

    this.addComponent(new Label("This is the main view 1"));

    int i = 1;
    createSubViewButtons(i++ , Constants.DASHBOARD, new DashboardView());
    createSubViewButtons(i++ , Constants.SCHEDULE, new ScheduleView());

}

private void createSubViewButtons(int exNum, String caption, View view) {
    navigator.addView(caption, view);

    Button button = new Button(caption, new ClickListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void buttonClick(ClickEvent event) {

            navigator.navigateTo(event.getButton().getData().toString());

        }
    });

    button.setData(caption);
    button.setStyleName(Reindeer.BUTTON_DEFAULT);

    this.addComponent(button);
}

我有一个实现 ViewProvider 的 class。 这基本上应该将 URL 映射到视图。 getViewName() 方法删除了 url 中不需要的部分,并且 getView() 应该 return 基于 getViewName() 的 return 值的 View 实例。 (无论如何,我有一种强烈的感觉,代码执行永远不会到这里,因为异常发生得更早)

public class ViewProviderImpl implements ViewProvider {

private static final long serialVersionUID = 1L;

private static Map<String, View> mapping;

static {
    mapping =  new HashMap<String, View>();
    ScheduleView scheduleView = new ScheduleView();
    DashboardView dashboardView = new DashboardView();
    mapping.put("CORE/maintain/schedule", scheduleView);
    mapping.put("CORE/maintain/dashboard", dashboardView);
    mapping.put(Constants.DASHBOARD, dashboardView);
    mapping.put(Constants.SCHEDULE, scheduleView);
}

public ViewProviderImpl(MainView mv) {
    mapping.put("", mv);
}

@Override
public String getViewName(String viewAndParameters) {

    // to do --if it is non empty than take it otherwise use Page 

    StringBuilder sb = new StringBuilder();
    String fullURL = Page.getCurrent().getLocation().toString();
    String fullURL = viewAndParameters;

    String arr[] = fullURL.split(Constants.ARRANGER_WITH_SLASH);
    if (arr.length > 1) {

        String shortURL = arr[1];

        if (shortURL.contains(Constants.QUESTION_MARK)) {
            shortURL = shortURL.split("\?")[0];
        }
        if (shortURL.contains(Constants.SLASH)) {
            // always remove the two first and keep the rest of it.
            String split[] = shortURL.split(Constants.SLASH);
            for (int i = 0; i < split.length; i++ ) {
                if (i <= 1) {
                    continue;
                }
                sb.append(split[i]);
                if (i >= 2 && i != split.length - 1) {
                    sb.append(Constants.SLASH);
                }
            }
        }
    }
    return sb.toString();
}

对我来说,这似乎合乎逻辑。实际上,它会抛出 NPE。为什么? 可能我滥用了 Vaadin7 中应该如何使用导航的方式,但我不知道该怎么办...

java.lang.NullPointerException
    vaadinacrys.MainView.createSubViewButtons(MainView.java:39)
    vaadinacrys.MainView.<init>(MainView.java:33)
    vaadinacrys.PoolarrangerUI.init(PoolarrangerUI.java:36)
    com.vaadin.ui.UI.doInit(UI.java:641)
    com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:222)
    com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
    com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1402)
    com.vaadin.server.VaadinServlet.service(VaadinServlet.java:295)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

按照我原来的评论,你没有完整地发布你的 MainView class 但是在它的构造函数中你没有将 Navigator navigator 变量分配给一个字段也没有将它传递为createSubViewButtons 方法的参数,以便您可以在那里使用它。如果您确实有一个名为 navigator 的字段,那么在执行 navigator.addView(caption, view); 时它将为空,因此您会得到一个 NPE。快速修复,this.navigator = navigator 在你的构造函数中享受。