我正在研究一个简单的Java应用程序。目前,我有两个视图,一个用于登录和另一个登录。控制器是否创建新视图?
所以我的问题是,一旦用户登录,登录视图的控制器应该创建第二个视图?
的问题是,第一控制器需要知道第二种观点的每一个依赖...
编辑:这是不是一个 Web应用程序。
我正在研究一个简单的Java应用程序。目前,我有两个视图,一个用于登录和另一个登录。控制器是否创建新视图?
所以我的问题是,一旦用户登录,登录视图的控制器应该创建第二个视图?
的问题是,第一控制器需要知道第二种观点的每一个依赖...
编辑:这是不是一个 Web应用程序。
如果你的对象需要实例化一个类,但你不希望它依赖实例化类的细节,请注入一个工厂(如you've suggested)。
我喜欢使用接口,所以我可以插入我的依赖项的不同实现。这里有一个例子:
public class RealLoginController implements LoginController {
private LoginViewFactory viewFactory;
public LoginController(LoginViewFactory viewFactory) {
this.viewFactory = viewFactory;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) {
if (isLoggedIn()) {
return viewFactory.createLoggedInView();
} else {
return viewFactory.createLoggedOutView();
}
}
// ...
}
public class RealLoggedInView implements LoginView {
// Implementation for rendering stuff
}
public class RealLoggedOutView implements LoginView {
// Implementation for rendering stuff
}
public interface LoginViewFactory {
public LoginView createLoggedInView();
public LoginView createLoggedInView();
}
public class RealLoginViewFactory implements LoginViewFactory {
private FooModel fooEngine;
private BarConfig barConfig;
public RealLoginViewFactory(FooModel fooLayer, BarConfig barConfig) {
this.fooEngine = fooEngine;
this.barConfig = barConfig;
}
public LoginView createLoggedInView() {
if (fooEngine.hasBaz()) {
return new RealLoginView(barCongig.getQux());
} else {
return new RealLoginView(barCongig.getQux(),
fooEngine.getBaz());
}
}
public LoginView createLoggedOutView() {
// ...
}
}
public class RealLoginController implements LoginController {
private LoginViewFactory viewFactory;
public LoginController(LoginViewFactory viewFactory) {
this.viewFactory = viewFactory;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) {
if (isLoggedIn()) {
return viewFactory.createLoggedInView();
} else {
return viewFactory.createLoggedOutView();
}
}
// ...
}
然后,您可以使用任何意见控制器你喜欢:
public class LoginControllerTest {
public void testSomething() {
// ...
controller = new RealLoginController(fakeViewFactory);
assertHasTag("td#row1", controller.getRenderedStuff());
// ...
}
}
您可能能够避免这些问题(如bpappa suggests)如果您并不需要复杂的实例逻辑和你的框架知道如何通过名字获得你的依赖关系。
这是与Spring MVC?
如果您使用Spring MVC 2.5或更低版本而没有注释,则在handleRequest方法结束时返回ModelAndView对象。这包含视图信息(不管它是视图本身,如在重定向视图中,还是视图的名称)。您可以根据某种逻辑有条件地返回不同的视图。例如 -
handleRequest(HttpServletRequest request, HttpServletResponse response) {
// get user from session
if (user.isLoggedIn())
return new ModelAndView("loggedInView");
else
return new ModelAndView("notLoggedInView");
}
如果这是一个新的项目,虽然,你必须访问Java 1.5,我反而建议使用annotations-based Spring MVC,因为这样你可以返回任何你想要的弗里克。
对不起,没有。这不是一个网络应用程序。 – subb 2009-05-31 23:40:26
我认为,一个工厂可能做的伎俩:
public class LoginViewFactory
{
private depA;
private depB;
public LoginViewFactory(dependencyA, dependencyB)
{
depA = dependencyA;
depB = dependencyB;
}
LoginView create()
{
return new LoginView(depA, depB);
}
}
//and then pass this factory to my controller
new Controller(new LoginViewFactory(new A(), new B());
你觉得呢?
你应该采用与Spring相同的方法,让你的控制器返回一个视图名称。 然后让另一个类根据视图名称处理创建视图。
我认为你的第一个“视图”(登录页面)可以被认为是一个静态页面,因为通常它会成为第一个可访问的页面,因此可能没有控制器。
但是,假设您的网络应用程序中还有一些其他页面,并说您确实有一个控制器A(一种DispatchController),它将用户引导至登录页面。
一旦这个页面被提交,通常你将会有一个不同的控制器(说的LoginController),将引导(如果登录成功)的用户到你的第二个视图页面(页面登录)
那么底线是:对我来说,看起来你需要两个控制器,每个控制器都有不同的责任。
我不认为LoginController应该创建SecondView。一旦用户登录,LoginController应该发出登录成功的事件,任何关心该事件的Controller都应该采取适当的措施。
如果您使用DI,您最好将视图注入控制器。
不太清楚你的意思与你最后的声明,尽管如此留下未答复。
好吧,假设我的第二个视图的构造函数需要一个模型,负责创建这个视图的对象(这里是我的控制器)需要知道这个模型,继承视图的依赖关系。 – subb 2009-06-07 12:25:09
如果您的登录名是表单POST(它应该是),我会在成功登录后重定向到主页。
这样,如果用户在登录后在主页上点击刷新,那么他们不会得到有关重新提交POST的浏览器警告。
如果他们单击主页上的链接,然后单击后退按钮,则同样适用。
在春天你可以用这个语法来做到这一点。
return new ModelAndView(new RedirectView(homepage, true), model);
的“主页”参数会在你的Spring配置进行配置,并注入作为参数 - 它应该是一个相对URL在您的网站主页。
因为你重定向的主页控制器执行,所以这处理你的依赖问题。
添加了java标记。 – 2009-06-01 03:18:46