我知道类似以下三行
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
是一种老式的编码方式,在JSP版本2中存在一种避免JSP文件中出现Java代码的方法。什么是可选的JSP2行,这种技术叫什么?
我知道类似以下三行
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
是一种老式的编码方式,在JSP版本2中存在一种避免JSP文件中出现Java代码的方法。什么是可选的JSP2行,这种技术叫什么?
当前回答
从技术上讲,JSP在运行时都转换为Servlet。
JSP最初创建的目的是按照MVC模式分离业务逻辑和设计逻辑。因此,JSP在运行时技术上都是Java代码。
但为了回答这个问题,标记库通常用于将逻辑(删除Java代码)应用于JSP页面。
其他回答
当然,替换<%!计数器++;%>通过事件生产者-消费者体系结构,业务层被通知需要增加计数器,它会做出相应的反应,并通知演示者,以便他们更新视图。涉及到许多数据库事务,因为将来我们需要知道计数器的新值和旧值,是谁增加了它,以及考虑到了什么目的。显然,由于层是完全解耦的,因此需要进行序列化。您将能够在RMI、IIOP和SOAP上增加计数器。但只需要HTML,因为这是一个很平常的情况,所以不需要实现。您的新目标是在新的闪亮E7 64GB RAM服务器上达到每秒250次增量。
我有20多年的编程经验,大多数项目在第六节之前都失败了:可重用性可替换性OO能力可调试性可测试性可维护性甚至是必需的。其他由只关心功能的人运营的项目非常成功。此外,在项目中过早实现的僵硬的对象结构使代码无法适应规范的剧烈变化(也称为敏捷)。
因此,我认为在项目早期或不特别需要时定义“层”或冗余数据结构的活动是拖延。
JSTL为条件、循环、集合、get等提供标记。例如:
<c:if test="${someAttribute == 'something'}">
...
</c:if>
JSTL与请求属性一起工作——它们通常由Servlet在请求中设置,Servlet转发到JSP。
Wicket也是一种将Java与HTML完全分离的替代方案,因此设计师和程序员可以在彼此不了解的情况下一起工作并处理不同的代码集。
看看Wicket。
从技术上讲,JSP在运行时都转换为Servlet。
JSP最初创建的目的是按照MVC模式分离业务逻辑和设计逻辑。因此,JSP在运行时技术上都是Java代码。
但为了回答这个问题,标记库通常用于将逻辑(删除Java代码)应用于JSP页面。
自2001年taglibs(如JSTL)和EL(表达式语言,那些${}的东西)诞生以来,在JSP中使用scriptlets(那些<%%>的东西)确实非常不受欢迎。
scriptlets的主要缺点是:
可重用性:不能重用scriptlets。可替换性:不能使scriptlets抽象。OO能力:你不能利用继承/组合。可调试性:如果scriptlet中途抛出异常,则只会得到一个空白页面。可测试性:scriptlets不是可单元测试的。可维护性:每个saldo需要更多的时间来维护混合/杂乱/重复的代码逻辑。
Sun Oracle本身也建议在JSP编码约定中避免在(标记)类可能具有相同功能时使用scriptlet。以下是几个相关的例子:
根据JSP1.2规范,强烈建议在web应用程序中使用JSP标准标记库(JSTL),以帮助减少页面中对JSP脚本的需求。通常,使用JSTL的页面更容易阅读和维护。...如果可能,只要标记库提供了等效的功能,就避免使用JSP脚本。这使得页面更易于阅读和维护,有助于将业务逻辑与表示逻辑分开,并将使您的页面更容易演变为JSP 2.0风格的页面(JSP 2.0规范支持但不强调scriptlets的使用)。...本着采用模型-视图-控制器(MVC)设计模式来减少表示层与业务逻辑之间的耦合的精神,JSP脚本不应用于编写业务逻辑。相反,如果需要,可以使用JSP脚本将处理客户端请求返回的数据(也称为“值对象”)转换为适合客户端的格式。即使这样,使用前端控制器servlet或自定义标记也会更好。
如何替换scriptlet完全取决于代码/逻辑的唯一目的。这段代码通常被放在一个完整的Java类中:
如果您希望在每个请求中调用相同的Java代码,无论请求的页面是多少,例如,检查用户是否登录,那么实现一个过滤器并在doFilter()方法中相应地编写代码。例如。:public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出ServletException、IOException{if(((HttpServletRequest)请求).getSession().getAttribute(“user”)==null){((HttpServletResponse)响应).sendRedirect(“登录”);//未登录,重定向到登录页面。}其他{chain.doFilter(请求,响应);//已登录,请继续请求。}}当映射到覆盖感兴趣的JSP页面的适当的<url模式>时,就不需要复制粘贴整个JSP页面的同一段代码。如果您想调用一些Java代码来处理GET请求,例如,从数据库中预加载一些列表以显示在某个表中,如果需要,可以基于一些查询参数,然后实现一个servlet并在doGet()方法中相应地编写代码。例如。:protected void doGet(HttpServletRequest请求,HttpServletResponse响应)throws ServletException,IOException{尝试{List<Product>products=productService.List();//获取所有产品。request.setAttribute(“products”,products);//将产品存储在请求范围内。request.getRequestDispatcher(“/WEB-INF/products.jsp”).forward(请求,响应);//转发到JSP页面以在HTML表中显示它们。}catch(SQLException e){抛出新的ServletException(“检索产品失败!”,e);}}这种处理异常的方法更容易。数据库不是在JSP呈现过程中访问的,而是在显示JSP之前访问的。您仍然可以在DB访问引发异常时更改响应。在上面的示例中,将显示默认的错误500页面,您可以通过web.xml中的<errorpage>自定义该页面。如果您想调用一些Java代码来处理POST请求,例如从提交的HTML表单中收集数据并使用它进行一些业务处理(转换、验证、保存在DB中等),那么就实现一个servlet并在doPost()方法中相应地编写代码。例如。:protected void doPost(HttpServletRequest请求,HttpServletResponse响应)throws ServletException,IOException{字符串username=request.getParameter(“username”);字符串密码=request.getParameter(“password”);用户User=userService.find(用户名、密码);if(用户!=空){request.getSession().setAttribute(“user”,用户);//登录用户。response.sendRedirect(“home”);//重定向至主页。}其他{request.setAttribute(“message”,“未知用户名/密码。请重试。”);//将错误消息存储在请求范围中。request.getRequestDispatcher(“/WEB-INF/login.jsp”).forward(请求,响应);//转发到JSP页面以重新显示出现错误的登录表单。}}这种处理不同结果页目的地的方法更容易:在出现错误时重新显示带有验证错误的表单(在这个特定的示例中,您可以使用EL中的${message}重新显示它),或者在成功时只需转到所需的目标页。如果您想调用一些Java代码来控制执行计划和/或请求和响应的目标,那么根据MVC的Front Controller Pattern实现servlet。例如。:受保护的void服务(HttpServletRequest请求、HttpServletResponse响应)引发ServletException、IOException{尝试{Action Action=ActionFactory.getAction(请求);字符串视图=action.execute(请求,响应);if(view.equals(request.getPathInfo().substring(1)){request.getRequestDispatcher(“/WEB-INF/”+view+“.jsp”).forward(请求,响应);}其他{response.sendRedirect(视图);}}catch(异常e){抛出新ServletException(“执行操作失败。”,e);}}或者只是采用一个MVC框架,如JSF、Spring MVC、Wicket等,这样您最终只需要一个JSP/Facelets页面和一个JavaBean类,而不需要定制servlet。如果您想调用一些Java代码来控制JSP页面内的流,那么需要获取一个(现有的)流控制标记库,如JSTL核心。例如,在表格中显示列表<产品>:<%@taglib uri=“http://java.sun.com/jsp/jstl/core“prefix=”c“%>”...<表><c:forEach items=“${products}”var=“product”><tr><td>${product.name}</td><td>${product.description}</td><td>${product.price}</td></tr></c:forEach></table>由于XML样式的标记非常适合所有HTML,因此代码的可读性(因此可维护性更好)比带有各种大括号和大括号(“这个大括号到底属于哪里?”)的一堆scriptlet要好。一个简单的帮助是,通过向web.xml添加以下部分,配置web应用程序,以便在仍然使用scriptlet时抛出异常:<jsp配置><jsp属性组><url模式>*.jsp</url模式><脚本无效>true</脚本无效></jsp属性组></jsp配置>在Facelets(JSP的继承者)中,它是JavaEE提供的MVC框架JSF的一部分,已经不可能使用scriptlets。这样你就自动被迫以“正确的方式”做事。如果您想调用一些Java代码来访问和显示JSP页面中的“后端”数据,那么您需要使用EL(表达式语言),这些${}的东西。例如,重新显示提交的输入值:<input-type=“text”name=“foo”value=“${param.foo}”/>${param.foo}显示request.getParameter(“foo”)的结果。如果您想直接在JSP页面中调用一些实用程序Java代码
另请参见:
JSP、Servlet和JSF之间有什么区别?Servlet、ServletContext、HttpSession和HttpServletRequest/Response是如何工作的?使用JSP、Servlet和JDBC的基本MVC示例Java web应用程序中的设计模式JSP/Servlet的隐藏特性