使用ControllerServlet是JavaEE6的良好实践吗?
我在Oracle提供的针对JavaEE6的affablebean教程中了解了ControllerServlet的用法 它以一个servlet处理许多不同的URL请求而结束,如下所示:使用ControllerServlet是JavaEE6的良好实践吗?,java,jakarta-ee,Java,Jakarta Ee,我在Oracle提供的针对JavaEE6的affablebean教程中了解了ControllerServlet的用法 它以一个servlet处理许多不同的URL请求而结束,如下所示: @WebServlet(name = "ControllerServlet", loadOnStartup = 1, urlPatterns = { "/category", "/addToCart", "/viewCart", "/u
@WebServlet(name = "ControllerServlet",
loadOnStartup = 1,
urlPatterns = {
"/category",
"/addToCart",
"/viewCart",
"/updateCart",
"/checkout",
"/purchase",
"/chooseLanguage"})
public class ControllerServlet extends HttpServlet {
@EJB
private CategoryFacade categoryFacade;
@EJB
private OrderManager orderManager;
@Override
public void init() throws ServletException {
// store category list in servlet context
getServletContext().setAttribute("categories", categoryFacade.findAll());
}
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userPath = request.getServletPath();
// if category page is requested
if (userPath.equals("/category")) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
Category selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute("selectedCategory", selectedCategory);
// get all products for selected category
Collection<Product> categoryProducts = selectedCategory.getProductCollection();
// place category products in request scope
request.setAttribute("categoryProducts", categoryProducts);
}
// if cart page is requested
} else if (userPath.equals("/viewCart")) {
// TODO: Implement cart page request
userPath = "/cart";
// if checkout page is requested
} else if (userPath.equals("/checkout")) {
// TODO: Implement checkout page request
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// TODO: Implement language request
}
// use RequestDispatcher to forward request internally
String url = "/WEB-INF/view" + userPath + ".jsp";
try {
System.out.println("Redirecting to : "+url);
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
我想知道这对于JavaEE项目来说是否是一个好的实践?我正在考虑采用JavaEE作为一个项目的框架,该项目涉及一个小的程序员团队。我认为这个ControllerServlet鼓励他们在其中加入很多业务逻辑。这门课预计会持续很长时间,有很多if/else if。。。将来
那么,对于在大型项目中工作的这样一个ControllerServlet,您有什么建议呢?您正确地认为,如果您正在处理许多不同的操作,controller servlet将很快变得难以管理。按照您所勾勒出的天真方法,您将得到一大堆if或case语句 典型的解决方案是前端控制器模式,它将url映射分派到实际处理请求的其他代码。有许多相对简单的解决方案可以做到这一点(有人提到了命令模式),它是大多数web框架的关键部分。我可能不会在2016年编写自己的前端控制器。在支持基于注释的servlet的情况下,我会考虑在每个servlet的一个动作周围构造一个非常简单的应用程序(如微服务);根据需要处理尽可能多的http方法:DELETE、PUT、GET 但是,您可能还需要其他功能,例如模板、可重用的UI组件、奇特的url参数处理、对象到json映射(以及相反的)、子资源映射、内容协商、授权等,考虑可以应用于问题的众多java EE技术之一(JAX-RS、JSF、JSR 371)和每个.</P >的更多实现。 如果你公开一个api,我会考虑一个JAX-RS实现,比如jersey,用于某种类型的应用程序,可能就足够了:可能是一个单页web应用程序,通过ajax调用与后端通信。你可以使用nginx For apache为静态内容提供服务。对于成熟的框架,您可以选择实现JSF标准的基于组件的方法,也可以选择实现mvc1(JSR371)规范的基于操作的方法。您可以在这里了解不同之处:
您提到了在JSF和SpringMVC之间进行选择,前者是基于组件的,后者是基于操作的。目前只有一个JSR371的实现,Ozark,参考。如果这种区别对您的选择很重要,那么您可能会因为缺少JSR371实现而受到阻碍。但在我看来,基于行动的方法确实是未来。也许。请注意,这个控制器正在映射相关的行为。仅仅因为控制器servlet可以处理许多请求并不会使它太大。Restlets项目使用此模型,非常受欢迎。您也可以链接有问题的教程-如果有详细说明,您可能有兴趣阅读其基本原理。另外:这里没有实际实现的业务逻辑。这将出现在EJB中。业务逻辑!=servlet映射策略。在任何规模的项目上进行映射,这似乎是一个糟糕的想法;你是否需要一个“框架”取决于你实际上在做什么。如果您所做的只是将JSON转储到API使用者,那么只需要简单的映射和序列化。现代JEE对于许多项目来说已经足够了。(我不会使用它,但那只是我自己。)那么你不认为servlet/ejb:s是为这个“设计”的,尤其是新的?我想我不同意这一点。我只是在看发布的示例代码。您需要将这些url端点分派到其他代码。也许ejb路由提供了一种很好的方法来实现这一点。“对我来说,这似乎是一个沉重的负担”。@RobertMoskal是的,设置多个URL到同一个servlet的方式是不可靠的。但是JEE框架已经通过相同的注释机制处理rational映射。仅仅因为你可以做错事并不意味着你必须做错事,也不意味着它不适合现代开发。我已经修改了我的回答,以便更清楚地表明,我的批评只是关于实现你自己的前端控制器,用一个servlet处理许多不同的操作。