Template和JSP技术

springboot 视图 Template、JSP 加载说明 最近将 springboot 升级到 3.3.0 版本;java 升级到 21 后,发现打包成 jar 后启动时,访问不到 JSP了;但通过 mvn spring-boot:run 命令启动可以正常访问;原来 jsp 文件放在 META-INF/resources/ 目录下;使用 1.4.2.RELEASE 版本的maven-spring-boot-plugin 插件打包,使用 3.3.0 版本的插件打包; 阅读详情

一、起源与现状:

关于Template和JSP的起源还要追述到Web开发的远古年代,那个时候的人们用CGI来开发web应用,在一个CGI程序中写HTML标签。

在这之后世界开始朝不同的方向发展:sun公司提供了类似于CGI的servlet解决方案,但是无论是CGI还是servlet都面对同一个问题:在程序里写html标签,无论如何都不是一个明智的解决方案。于是sun公司于1999年推出了JSP技术。而在另一个世界里,以PHP和ASP为代表的scriptlet页面脚本技术开始广泛应用。

不过即便如此,问题并没有结束,新的问题出现了:业务和HTML标签的混合,这个问题不仅导致页面结构的混乱,同时也使代码本身难以维护。

于是来自起源于70年代后期的MVC模式被引入开发。MVC的三个角色:Model——包含除UI的数据和行为的所有数据和行为。View是表示UI中模型的显示。任何信息的变化都由MVC中的第三个成员来处理——控制器。

在之后的应用中,出现了技术的第一次飞跃:前端的显示逻辑和后端的业务逻辑分离,COM组件或EJB或CORBA用于处理业务逻辑,ASP、JSP以及PHP被用于前端的显示。这个就是Web开发的Model 1阶段(页面控制器模式)。

不过这个开发模式有很多问题:

1.       页面中必须写入Scriptlet调用组件以获得所必需的数据。

2.       处理显示逻辑上Scriptlet代码和HTML代码混合交错。

3.       调试困难。JSP被编译成servlet,页面上的调试信息不足以定位错误。

这一切都是因为在Model 1中并没有分离视图和控制器。完全分离视图和控制器就成了必须。这就是Model 2。它把Model 1中未解决的问题——分离对组件(业务逻辑)的调用工作,把这部分工作移植到了控制器。现在似乎完美了,不过等等,原来的控制器从页面中分离后,页面所需的数据怎么获得,谁来处理页面显示逻辑?两个办法:1. 继续利用asp,php或者jsp等机制,不过由于它们是运行在web环境下的,他们所要显示的数据(后端逻辑产生的结果)就需要通过控制器放入request流中;2. 使用新手法——模板技术,使用独立的模板技术由于脱离的了web环境,会给开发测试带来相当的便利。至于页面所需数据传入一个POJO就行而不是request对象。

模板技术最先开始于PHP的世界,出现了PHPLIB Template和FastTemplate这两位英雄。不久模板技术就被引入到java web开发世界里。目前比较流行的模板技术有:XSTL,Velocity,JDynamiTe,Tapestry等。另外因为JSP技术毕竟是目前标准,相当的系统还是利用JSP来完成页面显示逻辑部分,在Sun公司的JSTL外,各个第三方组织也纷纷推出了自己的Taglib,一个代表是struts tablib。

二、 模板技术分析:

模板技术从本质上来讲,它是一个占位符动态替换技术。一个完整的模板技术需要四个元素:0. 模板语言,1. 包含模板语言的模板文件,2. 拥有动态数据的数据对象,3. 模板引擎。以下就具体讨论这四个元素。(在讨论过程中,我只列举了几个不同特点技术,其它技术或有雷同就不重复了)

1.       模板语言:

模板语言包括:变量标识和表达式语句。根据表达式的控制力不同,可以分为强控制力模板语言和弱控制力模板语言。而根据模板语言与HTML的兼容性不同,又可以分为兼容性模板语言和非兼容性模板语言。

模板语言要处理三个要点:

1. 标量标记。把变量标识插入html的方法很多。其中一种是使用类似html的标签;另一种是使用特殊标识,如Velocity或者JDynamiTe;第三种是扩展html标签,如tapestry。采用何种方式有着很多考虑,一个比较常见的考虑是“所见即所得”的要求。

2. 条件控制。这是一个很棘手的问题。一个简单的例子是某物流陪送系统中,物品数低于一定值的要高亮显示。不过对于一个具体复杂显示逻辑的情况,条件控制似乎不可避免。当你把类似于<IF condition=”$count <= 40”><then><span class=”highlight”>count </span></then></IF>引入,就象我们当初在ASP和PHP中所做得一样,我们将不得不再一次面对scriptlet嵌入网页所遇到的问题。我相信你和我一样并不认为这是一个好得的编写方式。实际上并非所有的模板技术都使用条件控制,很多已有的应用如PHP上中的以及我曾见过一个基于ASP.NET的应用,当然还有Java的JDynamiTe。这样网页上没有任何逻辑,不过这样做的代价是把高亮显示的选择控制移交给编程代码。你必需做个选择。也许你也象我一样既不想在网页中使用条件控制,也不想在代码中写html标记,但是这个显示逻辑是无可逃避的(如果你不想被你的老板抄鱿鱼的话),一个可行的方法是用CSS,在编程代码中决定采用哪个css样式。特别是CSS2技术,其selector机制,可以根据html类型甚至是element的attributes来apply不同的样式。

3. 迭代(循环)。在网页上显示一个数据表单是一个很基本的要求,使用集合标签将不可避免,不过幸运的是,它通常很简单,而且够用。特别值得一提的是PHP的模板技术和JDynamiTe技术利用html的注释标签很简单的实现了它,又保持了“所见既所得”的特性。

下面是一些技术的比较:

Velocity

变量定义:用$标志

表达式语句:以#开始

强控制语言:变量赋值:#set $this = "Velocity"

            外部引用:#include ( $1 )

            条件控制:#if …. #end

非兼容语言

JDynamiTe

变量定义:用{}包装

表达式语句:写在注释格式(<!--  à)中

弱控制语言

兼容语言

XSLT

变量定义:xml标签

表达式:xsl标签

强控制语言:外部引用:import,include

            条件控制:if,  choose…when…otherwise

非兼容语言

Tapestry

采用component的形式开发。

变量定义(组件定义):在html标签中加上jwcid

表达式语句:ognl规范

兼容语言

 

2.       模板文件:

模板文件指包含了模板语言的文本文件。

模板文件由于其模板语言的兼容性导致不同结果。与HTML兼容性的模板文件只是一个资源文件,其具有良好的复用性和维护性。例如JDynamiTe的模板文件不但可以在不同的项目中复用,甚至可以和PHP程序的模板文件互用。而如velocity的非兼容模板文件,由于其事实上是一个脚本程序,复用性和可维护性大大降低。

3.       拥有动态数据的数据对象:

模板文件包含的是静态内容,那么其所需的动态数据就需要另外提供。根据提供数据方式的不同可以分为3种:

1.       Map:利用key/value来定位。这个是最常见的技术。如velocity的VelocityContext就是包含了map对象。

Example.vm:

Hello from $name in the $project project.

 

Example.java:

VelocityContext context = new VelocityContext();

context.put("name", "Velocity");

context.put("project", " Jakarta ");

 

2.       DOM:直接操作DOM数据对象,如XSLT利用XPath技术。

3.       POJO:直接利用反射取得DTO对象,利用JavaBean机制取得数据。如Tapestry。

4.       模板引擎:

模板引擎的工作分为三步:

1. 取得模板文件并确认其中的模板语言符合规范。

比如velocity,确定#if有对应得#end等。Xml+xslt的模型中,xml文件标签是否完整等。在完成这些工作后,模板引擎通常会把模板文件解析成一颗节点树(包含模板文件的静态内容节点和模板引擎所定义的特殊节点)。

2. 取得数据对象。

        该数据对象一般通过程序传递引用实现。现有的大量框架在程序底层完成,处理方式也各自不同,有两种技术分别为推技术和拉技术。推技术:controller调用set方法把动态数据注入,模板引擎通过get方法获得,典型代表:Struts;拉技术:模板引擎根据配置信息,找到与view对应的model,调用model的get方法取得数据,典型代表:Tapestry。

3. 合并模板文件(静态内容)和数据对象(动态内容),并生成最终页面。

        合并的机制一般如下,模板引擎遍历这颗节点树的每一个节点,并render该节点,遇到静态内容节点按正常输入,遇到特殊节点就从数据对象中去得对应值,并执行其表达式语句(如果有的话)。

以下详细说明:

Velocity

Template template = Velocity.getTemplate("test.wm");

Context context = new VelocityContext();

context.put("foo", "bar");

context.put("customer", new Customer());

template.merge(context, writer);

当调用Velocity.getTemplate 方法时,将调用ResourceManger的对应方法。

ResourceManger先查看该模板文件是否在cache中,如果没有就去获取,生成resource对象并调用process()方法,确定该模板是否有效,如果有效,则在内存中生成一个Node树。

当调用template.merge()时,遍历这颗Node树,并调用每个Node的render方法。对于模板中的变量和对象Node,还将调用execute()方法,从context中取得value。

   注:ResourceManger在runtime/resource包下,Node在runtime/parser/node包下

Tapestry

Tapestry比较麻烦,先介绍一下http请求的处理过程。

当httprequest请求到达时。该请求被ApplicationServlet捕获,随后ApplicationServlet通过getEngine取到对应的Engine,通过该engine的getService拿到对应的service,调用其service方法执行http请求。

每个service通过RequestCycle对象的getPage方法取得Page对象,并将其设置为该Cycle对象的active Page。之后service调用renderResponse方法执行输出。

renderResponse调用page的getResponseWriter(output)取得writer对象,并把它传给cycle.renderPage(writer)方法,该方法调用page的renderPage方法。

Page执行renderPage时,首先判断是否有listener的请求,如果有则处理listener请求;然后调用BaseComponentTemplateLoader的process方法把模板文件载入并形成一个component节点树,依次执行节点的renderComponent方法。

每个component对象将通过ongl的机制取得对象属性。并把该值写入输入流。

例如:insert component

protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {

        if (cycle.isRewinding())

            return;

        Object value = getValue();

        if (value == null)

            return;

        String insert = null;

        Format format = getFormat();

        if (format == null) {

            insert = value.toString();

        }

        else{

            try{

                insert = format.format(value);

            }

            catch (Exception ex) {

                throw new ApplicationRuntimeException(

Tapestry.format("Insert.unable-to-format",value),this, getFormatBinding().getLocation(), ex);

            }

        }

        String styleClass = getStyleClass();

        if (styleClass != null) {

            writer.begin("span");

            writer.attribute("class", styleClass);

            renderInformalParameters(writer, cycle);

        }

        if (getRaw())

            writer.printRaw(insert);

        else

            writer.print(insert);

        if (styleClass != null)

            writer.end(); // <span>

    }

getValue为取得insert的value属性。

 

三、JSP技术分析

       1. JSP技术:

       JSP,一个伪装后的servlet。web server会对任何一个jsp都生成一个对应jsp类,打开这个类,就会发现,jsp提供的是一个代码生成机制,把jsp文件中所有的scriptlet原封不动的copy的到生成的jsp类中,同时调用println把所有的html标签输出。

Test.jsp:

<html>

<head><title>jsp test</title></head>

<body>

<table width="226" border="0" cellspacing="0" cellpadding="0">

   <tr><td><font face="Arial" size="2" color="#000066">

             <b class="headlinebold">The jsp test file</b>

       </tr></td> </font>  

</table>

<body>

</html>

Test_jsp.java:

package org.apache.jsp;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

import org.apache.jasper.runtime.*;

 

public class Test _jsp extends HttpJspBase {

  private static java.util.Vector _jspx_includes;

  public java.util.List getIncludes() {

    return _jspx_includes;

  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)

        throws java.io.IOException, ServletException {

    JspFactory _jspxFactory = null;

    javax.servlet.jsp.PageContext pageContext = null;

    HttpSession session = null;

    ServletContext application = null;

    ServletConfig config = null;

    JspWriter out = null;

    Object page = this;

    JspWriter _jspx_out = null;

 

    try {

      _jspxFactory = JspFactory.getDefaultFactory();

      response.setContentType("text/html;charset=ISO-8859-1");

      pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);

      application = pageContext.getServletContext();

      config = pageContext.getServletConfig();

      session = pageContext.getSession();

      out = pageContext.getOut();

      _jspx_out = out;

 

      out.write("<html>/r/n");

      out.write("<head><title>jsp test</title></head> /r/n");

      out.write("<body>/r/n");

      out.write("<table width=/"226/" border=/"0/" cellspacing=/"0/" cellpadding=/"0/">/r/n   ");

      out.write("<tr><td><font face=/"Arial /" size=/"2/" color=/"#000066/"> /r/n/t      ");

      out.write("<b class=/"headlinebold/">The jsp test file");

      out.write("</b>/r/n/t      ");

      out.write("</tr></td></font>/r/n/t ");

      out.write("</table>/r/n");

      out.write("<body>/r/n");

      out.write("</html>");

    } catch (Throwable t) {

      out = _jspx_out;

      if (out != null && out.getBufferSize() != 0)

        out.clearBuffer();

      if (pageContext != null) pageContext.handlePageException(t);

    } finally {

      if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);

    }

  }

}

 

       2. Taglib技术:

Taglib作为jsp之上的辅助技术,其工作本质依托与jsp技术,也是自定义标签翻译成java代码,不过这次和jsp略有不同,它还要经过几个过程。

先来看一下,实现一个tag的2个要点:

1. 提供属性的set方法,此后这个属性就可以在jsp页面设置。以jstl标签为例 c:out value=""/,这个value就是jsp数据到tag之间的入口。所以tag里面必须有一个setValue方法,具体的属性可以不叫value。例如setValue(String data){this.data = data;}。这个“value”的名称是在tld里定义的。取什么名字都可以,只需tag里提供相应的set方法即可。

2. 处理 doStartTag 或 doEndTag 。这两个方法是 TagSupport提供的。还是以c:out value=""/为例,当jsp解析这个标签的时候,在“<”处触发 doStartTag 事件,在“>”时触发 doEndTag 事件。通常在 doStartTag 里进行逻辑操作,在 doEndTag 里控制输出。

  在处理tag的时候:

  0. 从tagPool中取得对应tag。

1.     为该tag设置页面上下文。

2.     为该tag设置其父tag,如果没有就为null。

3.     调用setter方法传入标签属性值tag,如果该标签没有属性,此步跳过。

4.     调用doStartTag方法,取的返回值。

5.     如果该标签有body,根据doStartTag返回值确定是否pop该标签内容。如果要pop其body,则:setBodyContent(),在之后,doInitBody()。如果该标签没有body,此步跳过。

6.     调用doEndTag()以确定是否跳过页面剩下部分。

7.     最后把tag类返还给tagPool。

tag类为:

package my.customtags;

import javax.servlet.jsp.JspWriter;

import javax.servlet.jsp.PageContext;

import javax.servlet.jsp.tagext.TagSupport;

 

public class Hidden extends TagSupport{

    String name;  

    public Hidden(){    name = "";    }

    public void setName(String name){    this.name = name;    }

    public void release(){   value = null;    }

    public int doStartTag(){  return EVAL_BODY_INCLUDE;}

public int doEndTag() throws JspTagException{

   try{   pageContext.getOut().write(", you are welcome");   }

   catch(IOException ex){   throw new JspTagException("Error!");    }

   return EVAL_PAGE;

}

}

 

Jsp页面:

<my:hidden name="testname"/>

 

生成的jsp代码:

my.customtags.Hidden _jspx_th_my_hidden_11 = (my.customtags.Hidden) _jspx_tagPool_my_hidden_name.get(my.customtags.Hidden.class);

_jspx_th_my_hidden_11.setPageContext(pageContext);

_jspx_th_my_hidden_11.setParent(null);

_jspx_th_my_hidden_11.setName("testname");

int _jspx_eval_my_hidden_11 = _jspx_th_my_hidden_11.doStartTag();

if (_jspx_th_my_hidden_11.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)

   return true;

_jspx_tagPool_my_hidden_name.reuse(_jspx_th_my_hidden_11);

return false;

 

   Taglib技术提供两个机制,Body和non-Body导致了taglib的出现了两个分支:Display Tag和Control Tag, 前者在java code中嵌入了html标签,相当与一个web component,而后者则是另一种模板脚本。

 

四、两种技术方案的比较:

       1. 技术学习难易度

模板技术。使用模板技术,第一点就是必须学习模板语言,尤其是强控制的模板语言。于是模板语言本身的友好性变的尤为重要。以下依据友好性,表现力以及复用性三点为主基点比较了一下几种模板技术。

Velocity:

Turbine项目(http://jakarta.apache.org/Turbine)采用了velocity技术。

1.       友好性不够。理由: 强控制类型,出现页面显示控制代码和html混合。与Html的不兼容,无法所见即所得。遇到大的HTML页面,从一个 “#if”找到对应的 “#end”也是很痛苦的一件事情。

2.       表现力强。理由:强控制语言。

3.       复用性弱。理由:模板脚本和页面代码混合。

XSLT

Cocoon项目(http://cocoon.apache.org/)采用XML + XSLT的方法。优快云社区也是采用此方案。

1.       内容和显示风格分离,这点XSLT做的最好。

2.       速度慢。理由:XSLT的使用XPath,由于是要解析DOM树,当XML文件大时,速度很慢。

3.       友好性不够。理由:由于没有HTML文件,根本看不到页面结构、显示风格和内容。XSL语法比较难以掌握,由于没有“所见即所得”编辑工具,学习成本高。

4.       表现力强。理由:强控制语言。

5.       复用性弱。理由:xsl标签和html标签混合。

JDynamiTe

1.       表现力中等。理由:弱控制语言。

2.       友好性强。理由:所见即所得的效果。在模板件中的ignore block在编辑条件下可展示页面效果,而在运行中不会被输出。

3.       复用性强。理由:利用html标签。

Tapestry

1.       友好性中等。理由:整个Tapestry页面文件都是HTML元素。但是由于component会重写html标签,其显示的样子是否正确,将不预测。

2.       表现力强。理由:强控制语言。

3.       复用性强。理由:扩展了HTML元素的定义。

 

 

在JSP中大量的使用TagLib,能够使得JSP的页面结构良好,更符合XML格式,而且能够重用一些页面元素。但TagLib的编译之后的代码庞大而杂乱。TabLib很不灵活,能完成的事情很有限。TabLib代码本身的可重用性受到TagSupport定义的限制,不是很好。 另外是,我不得不承认的一件事是,TagLib的编写本身不是一件愉快的事情,事实我个人很反对这种开发方式。

 

       2. 技术使用难易度

       模板技术:模板技术本身脱离了Web环境,可以在不启动Web server得情况下进行开发和测试,一旦出错详细的信息易于错误的定位。由于模板引擎的控制,页面中将只处理显示逻辑(尽管其可能很复杂)

       JSP技术:工作在Web环境下,开发测试一定要运行web server。此外,一些TagLib能够产生新的标签,页面的最终布局也必须在web环境下才可以确定。测试时出错信息不明确,特别是TagLib得存在,极不容易定位。由于其本质是程序,很容易在其中写入业务逻辑,甚至于数据库连接代码,造成解耦的不彻底。

 

3. 总结

模板技术更加专注于页面的显示逻辑,有效帮助开发人员分离视图和控制器。在学习,开发和测试都更加容易。

JSP 技术本身是一个早期的技术,本身并没有提出足够的方式来分离视图和控制器。相反,我认为其本身是鼓励开发人员不做解
jsp默认模板 做模板用, 立即下载

相关推荐

Linux Component概述和高通component的使用

为了让subsystem按照一定顺序初始化设备才提出来的。subsystem中由很多设备模块,内核加载这些模块的时间不确定。子系统内有些模块是需要依赖其它模块先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video device),这时就要用到component框架。例如v4l2 subdev和v4l2 video device中,谁依赖谁先创建?

lz_1990的专栏 1610

jsp template之我见

我们在做程序的过程中,常常会遇到这样一种情况,就是在一个项目中,会发现有很多页面的框架基本相同的,只是具体显示的内容不同,而按常规的做法,我们可能会用include语句来提出框架内容,然后在每个页面中引用这些框架,但这样就会产生一个问题,如果我的框架发生变化了,那应该怎么办呢?举个例子,一个index.jsp可能包含有head.jsp和foot.jsp。而其它页面也同样包含这两个JSP。但如果我在

jeff技术博客 2812

CH376S模块实战:如何通过串口轻松实现单片机与U盘的数据交互

本文详细介绍了如何利用CH376S模块,通过串口通信实现单片机与U盘的数据交互。文章从模块原理、硬件连接到核心指令集进行了全面解析,并提供了基于STM32的实战代码示例。CH376S模块极大地简化了USB协议和文件系统的复杂性,使开发者能快速为嵌入式设备添加便捷的数据存储与导出功能,适用于数据记录、配置导入等多种应用场景。

weixin_29165725的博客 458

JSP模板应用指南(上)

Window 工具包提供了一种典型的布局机制,比如说在一个容器中确定部件元素的位置。在AWT 和 Swing都有布局管理器,而在VisualWorks Smalltalk中有wrapper。本文将介绍一种JSP模板机制,它允许布局被封装和重新利用。JSP模板最小化了布局改变所造成的影响,这里我们将鼓励大家采用封装模块化设计。   尽管 Web开发工具的改进非常迅速,但是它们仍然落后于图形

SAIN 696

ODBC 连接数据库 SQL server 2008

1、打开【控制面板】-> 【系统和安全】 -> 【管理工具】-> 【数据源(ODBC)】  2、双击【数据源(ODBC)】-> 选中【系统DSN】 3、单击【添加】,会弹出如下对话框,选中【SQL server】->【完成】 4、弹出如下对话框,在【名称】中填入数据源名称 例如:我命名为: LocalServer,在【服务器】中填入计算机名或者IP地址,我连接

Christine的专栏 8518

MIKE21 教程 3.2 随空间变化的网格文件制作(.dfsu文件制作) 曼宁值网格文件制作

上一节讲解了如何制作时间序列文件。本节讲解如何制作仅随空间变化的文件。 目录 1 数据准备 1.1 基于地形设置 1.2 基于地形水深设置: 2 数据导入 3 数据导出

Hello Word 3941

springboot如何使用jsp/templates

一:如何使用jsp 1.springboot默认是不支持jsp的,要想用jsp的话,需要导一个插件,在pom.xml里添加依赖 &lt;dependency&gt; &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt; &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&...

qq_43154385的博客 5020

YOLO26 无损剪枝:稀疏训练 + 结构化通道裁剪

YOLO26 无损剪枝链路:YOLO26s (7.2M) → 稀疏训练 30 epoch (L1 on BN gamma, lam=0.01) → 阈值剪枝 50% (gamma<quantile(0.5)) → 结构化重建 Conv+BN → 微调 10 epoch (lr=1e-4) → YOLO26n (1.9M, mAP50 0.808, 仅降 0.6%)。核心贡献:稀疏训练让 BN gamma 趋向二元分布 (近 0 或近 1), 剪枝阈值可直接取 median 自动 50% 压缩。

m0_64661770的博客 263

使用jsp模板——template.js

附上github地址 用script圈出一部分区域,用来存放模板 注意 1、要有id2、type类型是text/html3、{{each list as value i}}圈出遍历范围4、{{value.xxx}}用来取值 <script id="goodStore" type="text/html"> {{each list as value i}} <div class="gs-

我给媳妇儿讲java 6114

YOLOv11涨点改进 | Neck改进篇 | YOLOv11引入 BiFPN双向特征金字塔网络,显著提升了多尺度特征融合效率

本文介绍了基于BiFPN特征融合模块优化的YOLOv11目标检测模型。BiFPN通过双向跨尺度连接和加权特征融合机制,显著提升了多尺度特征融合效率。该方法在COCO数据集上实现了55.1AP的检测精度,同时大幅降低计算成本(减少13-42倍FLOPs)。文章详细解析了BiFPN模块结构、核心代码实现方法,并提供了YOLOv11-BiFPN配置文件的修改指导,为计算机视觉领域提供了一种高效的目标检测解决方案。

Ai缝合怪、助力小伙伴高效发论文 717

DC/DC开关电源学习笔记(十三)Buck-Boost升降压电路工作原理

Buck-Boost电路是一种能够实现输出电压高于或低于输入电压的DC-DC变换器,且输出电压极性与输入电压相反。它结合了Buck(降压)和Boost(升压)两种拓扑的特点,广泛应用于需要灵活电压调整的场合,如电池供电设备、LED驱动和工业控制系统。本文将从电路结构、工作原理、关键公式推导及实际应用等方面进行详细分析。

小幽余生不加糖 3505

利用模板template动态渲染jsp页面

一、场景 在js中写html简直是噩梦,刚进新公司,在codereview的时候得知可以通过将html模板写在jsp页面,然后由js调取模板,利用replace()方法替换传值的方式避免在js中拼接html代码,尝试后,成功利用这种方式完成一个模块的增删查改。 二、具体方式 1. 在jsp页面编写模板,以花括号放置待替换的值 注意定义模板type="text/templat...

weixin_30423977的博客 1426

ardupilot BMI088加速度陀螺仪学习

本节主要记录ardupilot 中BMI088传感器的学习过程,欢迎批评指正。BMI088是一款高性能6轴惯性传感器,由16位数字三轴±24g加速度计和16位数字三轴±2000°/ s陀螺仪组成。 BMI088允许高精度测量方向和沿三个正交轴的运动检测。BMI088具有高振动鲁棒性和3 x 4.5 x0.95mm³的小尺寸,是用于无人机和机器人应用等恶劣环境的高性能IMU中的独特产品。 BMI088专门设计用于有效抑制由于PCB上的共振或整个系统的结构而可能发生的振动。 除了高振动稳定性外,BMI088的出

陌城烟雨 2056

jsp:attribute

在传统 JSP 中,想要实现页面布局管理比较麻烦,为了解决在 JSP 中布局的问题,出现了很多开源软件,比如 Apache Tiles 和 SiteMesh 就是其中比较优秀的。但是使用开源软件实现布局或多或少会产生一些性能问题,有没有办法在不依赖第三方开源软件的情况下,使用 JSP 本身来实现页面布局呢?JSP 2.0 引入了 Fragment 技术,使用 Fragment 技术可以在 JSP...

weixin_30781433的博客 224

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

<jsp:invoke fragment=""/>的理解和使用

本文出自:http://www.tuicool.com/articles/ERFZvyy 在传统 JSP 中,想要实现页面布局管理比较麻烦,为了解决在 JSP 中布局的问题,出现了很多开源软件,比如 Apache Tiles 和 SiteMesh 就是其中比较优秀的。但是使用开源软件实现布局或多或少会产生一些性能问题,有没有办法在不依赖第三方开源软件的情况下,使用 JSP 本

537

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【Go语言开发实战】:为何你在Go中找不到JSP?彻底搞懂服务端模板技术选择

wu

FuncTide的博客 632

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java利用技巧——通过反射实现webshell编译文件的自删除

0x00 前言 我们知道,当我们访问jsp文件时,Java环境会先将jsp文件转换成.class字节码文件,再由Java虚拟机进行加载,这导致了Java服务器上会生成对应名称的.class字节码文件。对于webshell,这会留下痕迹。 为了实现自删除.class字节码文件,我们可以通过反射获得.class字节码文件的路径,再进行删除。本文将以Zimbra环境为例,结合AntSword-JSP-Template,分析利用思路。 0x01 简介 本文将要介绍以下内容: 通过反射实现...

HongYu012的博客 635

轻量级的代码生成方案选择

第3版--2005.6.22更新        上次说到MyAppfuse要有一个代码生成工具, codegeneration.net上汇集了各种平台各种语言的工具。    其实代码生成是和代码重复的bad smell一样古老的东西了,不过在这个时代里,大家充分发掘了继承,委托,反射,甚至AOP的之后,coding 依然boring,依然重复,这时候就需要从一个更抽象的层次去描述系统,然后再生成我

花钱的年华 8726

产生静态的hmtl文件

产生静态的hmtl文件 从publish.jsp开始执行,html.template是模板文件,publish.jsp提交给publishOK.jsp处理,生成静态的html文件! //html.template文件 &lt;html&gt;&lt;head&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=g...

编程资料大全 126

struts-bean.tld,struts-html.tld,struts-logic.tld 文件的作用

struts-html标签库。这个库可以被用来生成动态HTML用户界面和窗体。 struts-bean标签库。在将JavaBean代码放入JSP   页面时这个库提供实质性的加强的功能以改善其性能,它由标签提供。 struts-logic标签库。这个库可管理有条件的文本生成,在对象集合中循环以重复生成输出文本和应用程序流程管理。 struts-template标签库。在为具有

小苟的专栏 1768

jspwiki Processor

Just record some I got. Organize it later *.jsp->*Template.jsp->Tag.java->get something in WikiContext.java ->get mass from PageCommand.java to get default configure

Heraclesun 142

模板技术相对传统JSP技术有以下三个主要优势

模板技术相对传统JSP技术有以下三个主要优势:1. 在技术层面,将表现逻辑与业务逻辑相分离。2. 为人员间的分工提供了一个良好的分界点。页面美工只需专著关心模板的设计,而程序员则专注于业务逻辑的实现。二者重合点明显减少。3. 如果需要,模板引擎可脱离Web 容器单独运行,这为系统可能的移植需求提供了更多的弹性空间(这一特性在应用中也许并不会有太大的实际意义,只是提供了一种附加选择)...

学习笔记 438
上一篇: Java Web Framework综述
下一篇: Rich Client技术简介
emag_java
博客等级 码龄22年 29粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值