当前位置: 首页 > 知识库问答 >
问题:

在jersey Interceptor中缩小html和js

颛孙昆
2023-03-14

使用jersey mvc和jsp,所有对html或js文件的请求都通过@Template或Viewable完成。例子;

  @GET
  @Path(JS_URL + "{type}")
  @Template(name = "grid")
  @Produces("application/javascript")
  public Response buildJSGrid(@DefaultValue("") @PathParam("type") String type) {
     Grid grid = new Grid(type);
....
     return Response.ok(grid).build();
  }

其中grid是内部包含纯javascript的grid.jsp文件

<%@ page contentType="application/javascript;charset=UTF-8" language="java" %>

.....

也可能有html和js的其他变体,例如;

@GET
  @Path(FORM_URL + "{type}")
  @Template(name = "form")
  @Produces(MediaType.TEXT_HTML)
  public Response buildAccountForm(@DefaultValue("") @PathParam("type") String type) {
     Form form = new Form(type);
....
     return Response.ok(form).build();
  }

其中表单是表单.jsp里面有 html 和 js

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

...

我需要在发送到客户端之前缩小结果js和html/js,我尝试使用https://code.google.com/archive/p/htmlcompressor/库,但需要将字符串传递给html compressor . compress(input);

尝试使用WriterInterceptor

public class MinifyJsInterceptor implements WriterInterceptor {
  @Override
  public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
final OutputStream outputStream = context.getOutputStream();
// here need to convert outputStream to InputStream and after to String ?
// result string to htmlCompressor.compress(resultString);
// after that convert result minify string back to resultOutputStream and set to context ?
context.setOutputStream(new GZIPOutputStream(resultOutputStream));

这是正确的方法吗?我不能把输出流转换成字符串,谢谢

-更新

回答问题;html js的意思是在某些jsp中是html标记和js代码

    <div id="form" style="width: 500px; display: none">
      <div class="w2ui-page page-0">
        <div class="w2ui-field">
    </div>....

    <script type="text/javascript">
      var uiElement = (function () {
        var config = {
            onOpen: function (event) {
      event.onComplete = function () {
        $('#formContainer').w2render('form');
      }
     ...
    }());
    </script>

客户端上请求的文件

         $('#tempContainer').load('that file name - also dynamic', function (data, status, xhr) {
           uiElement.init();
           w2ui[layout].content(layout_main, w2ui[uiElement.name]);
         });

你真的在你的资源方法中返回js文件吗?

        some js and html + js files are dynamic build, example;
        grid.jsp contains inside

<%@ page contentType="application/javascript;charset=UTF-8" language="java" %>

          var uiElement = (function () {
            var config = {
              grid: {
                name: ${it.name},
                listUrl:'${it.entityListUrl}',
                formUrl:'${it.entityFormUrl}',
                columns: ${it.columns},
                records: ${it.records},           
}}

有来自资源方法中的 el 表达式和设置的 ${it..} 值

@GET
      @Path(JS_URL + "{type}")
      @Template(name = "grid")
      @Produces("application/javascript")
      public Response buildJSGrid(@DefaultValue("") @PathParam("type") String type) {
         Grid grid = new Grid(type);
    ....
         return Response.ok(grid).build();
      }}

并从客户端调用js“文件”

         $.getScript('dynamic js file name' - it is dynamic too).done(function (script, status, xhr) {
           //console.log(xhr.responseText);
           uiElement.init();
           w2ui[layout].content(layout_main, w2ui[uiElement.name]);
         });



       also some html blocks build dynamic


{ 
     <c:if test="${it.recid != 0}">
          <div class="w2ui-field">
            <label>active:</label>
            <div>
              <input name="active" type="checkbox"/>
            </div>
          </div>
            </c:if>
}

-- 更新描述,网格构建器;

一个资源和一个模板用于构建任何网格,

  @GET
  @Path(GRID + "{type}")
  @Template(name = W2UI_VIEW_PREFIX + "grid/grid")
  @Produces(MEDIA_TYPE_APPLICATION_JAVASCRIPT)
  public Response buildGrid(@DefaultValue("") @PathParam("type") String type) {
    for (W2UI ui : W2UI.values()) {
      if (type.equals(ui.getName())) {
        W2UIElement grid = ui.getUI();
        return Response.ok(grid).build();
      }
    }
    return Response.noContent().build();
  }

也可以通过Viewable(模板、模型)使用不同的模板(jsp文件)

菜单生成器中的某个位置。jsp模板

List<MenuItem> items..
MenuItem item1 = new MenuItem(W2UI.TASK_GRID, W2UIService.GRID);
items.add(item1);

在哪里

W2UIService.GRID is string url for client js request and for server method resource @Path() anno.

public enum W2UI {
  TASK_GRID("task_grid", "tasks", Type.SCRIPT){
    @Override
    public W2UIElement getUI() {
      return new TaskGrid(getName());
    }
  },
.....
}

TaskGrid是用js代码填充grid.jsp模板的模型,所以很容易添加任何类型的网格和不同的数据集和按钮。

组件类型(类型。脚本)在客户端上的处理。getScript(),Type.HTML by $(' # temp container ')。负载()

---更新工厂和供应商;

@Provider
@Priority(200)
@HtmlMinify
public class HtmlMinifyInterceptor implements WriterInterceptor {
  @Inject private HtmlCompressor compressor;

...

public class HtmlMinifierFactory implements Factory<HtmlCompressor> {
  private HtmlCompressor compressor;

  @Override
  public HtmlCompressor provide() {
    if (null == compressor) compressor = new HtmlCompressor();
    ClosureJavaScriptCompressor jsCompressor = new ClosureJavaScriptCompressor();
    jsCompressor.setCompilationLevel(CompilationLevel.SIMPLE_OPTIMIZATIONS);

@ApplicationPath("/")
public class MainRsConfig extends ResourceConfig {
  public MainRsConfig() {
..
    register(new AbstractBinder() {
      @Override
      protected void configure() {
        bindFactory(HtmlMinifierFactory.class).to(HtmlCompressor.class).in(Singleton.class);
      }
    });
..

共有1个答案

廖夜洛
2023-03-14
匿名用户

您可以使用ByteArrayOutputStream的自定义实现作为< code > writerceptorcontext 的< code>OutputStream的包装:

import com.googlecode.htmlcompressor.compressor.Compressor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class HtmlMinifyOutputStream extends ByteArrayOutputStream {

    private OutputStream origOut;
    private Compressor compressor;

    public HtmlMinifyOutputStream(OutputStream origOut, Compressor compressor) {
        this.origOut = origOut;
        this.compressor = compressor;
    }

    public void close() throws IOException {
        super.close();
        String compressedBody = compressor.compress(new String(this.buf));
        this.origOut.write(compressedBody.getBytes());
        this.origOut.close();
    }
}

HtmlMinifyOutputStream可用于WriterInterceptor实现。注入了HtmlCompressor实例:

import com.googlecode.htmlcompressor.compressor.Compressor;
import javax.inject.Inject;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import java.io.*;

@Provider
@HtmlMinify
public class MinifyHtmlInterceptor implements WriterInterceptor {

    @Inject
    private Compressor compressor;

    @Override
    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new HtmlMinifyOutputStream(outputStream, compressor));
        context.proceed();
    }
}

@HtmlMinify是一个NameBinding注释,用于激活特定资源方法上的MinifyHtmlInterceptor。(请参见https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9988):

import javax.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@NameBinding
@Retention(value = RetentionPolicy.RUNTIME)
public @interface HtmlMinify {}

每个应用程序只能创建一次< code>HtmlCompressor并同时使用,因为:

HtmlCompressor和XmlCompressor类被认为是线程安全的*,可以在多线程环境中使用< br > < I >(https://code . Google . com/archive/p/html compressor/)

下面是一个HK2工厂(请参见:实现定制注入提供程序),它创建压缩器实例并启用内联css和javascript压缩:

import com.googlecode.htmlcompressor.compressor.Compressor;
import com.googlecode.htmlcompressor.compressor.HtmlCompressor;
import org.glassfish.hk2.api.Factory;

public class HtmlCompressorFactory implements Factory<Compressor> {

    private HtmlCompressor compressor;

    @Override
    public Compressor provide() {
        if(compressor == null) {
            compressor = new HtmlCompressor();
        }
        compressor.setCompressJavaScript(true);
        compressor.setCompressCss(true);
        return compressor;
    }

    @Override
    public void dispose(Compressor compressor) {}
}

工厂是用AbstractBinder注册的:

final ResourceConfig rc = new ResourceConfig().packages("com.example");
rc.register(new AbstractBinder() {
    @Override
    protected void configure() {
        bindFactory(HtmlCompressorFactory.class).to(Compressor.class).in(Singleton.class);
    }
});

如果启用了内联脚本或内联 css 压缩:

具有默认设置的超文本标记语言压缩器不需要任何依赖项。
内联CSS压缩需要YUI压缩器库。
内联JavaScript压缩需要YUI压缩器库(默认情况下)或谷歌闭包编译器库。
(https://code.google.com/archive/p/htmlcompressor/)

我使用maven,因此我将此依赖项添加到pom.xml中:

<dependency>
    <groupId>com.yahoo.platform.yui</groupId>
    <artifactId>yuicompressor</artifactId>
    <version>2.4.8</version>
</dependency>

如果要使用Google Closure Compiler,请使用以下依赖项:

<dependency>
    <groupId>com.google.javascript</groupId>
    <artifactId>closure-compiler</artifactId>
    <version>r2388</version>
</dependency>

并激活它:

compressor.setJavaScriptCompressor(new ClosureJavaScriptCompressor());
compressor.setCompressJavaScript(true);
compressor.setCssCompressor(new YuiCssCompressor());
compressor.setCompressCss(true);
return compressor;

如果要压缩纯JavaScript或CSS文件,则不能使用< code>htmlcompressor。这个库只支持内嵌CSS/JS的HTML文件。但是您可以实现一个类似于< code>MinifyJsInterceptor的< code > minifycss interceptor ,它直接使用YUI压缩器和/或Google闭包库。

对于 gzip 压缩,您应该实现另一个拦截器。因此,可以单独配置缩小和压缩。如果激活多个拦截器,请使用 javax.annotation.优先级来控制执行顺序。(请参阅:https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9927)

 类似资料:
  • 一、压缩 js /* webpack.config.js webpack的配置文件 */ module.exports = { ………… //模式 development 开发环境,production 生产环境 //mode: 'development', //生产环境下会自动压缩js代码 mode: 'production' ……

  • 问题内容: 我有一个面板,其中正在移动一些2D对象。我已经根据需要重写了paintComponent()。现在,我希望能够放大和缩小该区域。放大时,将出现滚动条,通过滚动条可以滚动查看整个字段。在放大和缩小时,二维对象的大小应相应增加或减小。哪个Swing组件或什至是组件组合将有助于实现这一目标? 问题答案: 最简单的方法是修改面板并引入一个双倍来指示您的缩放级别。这双会指示你的规模,其中1是正常

  • 问题内容: 如何在Firefox和Opera中缩放HTML元素? 该属性可以在IE,Google Chrome和Safari中使用,但不能在Firefox和Opera中使用。 有什么方法可以将此属性添加到Firefox和Opera? 问题答案: 试试下面的代码,它将起作用:

  • 问题内容: 我需要减少Android应用程序中音频和视频文件的大小。我可以使用FFMPEG库吗,如果可以,请提供代码或一些教程链接的帮助。 或者,如果还有其他方法可以实现这一目标,请提出建议。 问题答案: 是的,您可以使用FFMPEG做到这一点。 快速的Google搜索: 在这里。

  • 问题内容: 我正在寻找一个可以减少我的php页面html输出的php脚本或类,就像google page speed一样。 我怎样才能做到这一点? 问题答案: CSS和Javascript 考虑以下链接以最小化Javascript / CSS文件: HTML 告诉Apache使用GZip交付HTML-这通常将响应大小减少了约70%。(如果使用Apache,则配置gzip的模块取决于您的版本:Apa

  • 问题内容: 我有一个缩进的JSON字符串,例如 但是,我没有要序列化或反序列化的实例的类型。 在我的情况下, 最小化* JSON字符串的 最有效方法 是什么?例如 * 我不介意使用可用于生产的库。 问题答案: 应该做。它确保保留包含空格字符的字符串,并丢弃所有其他空格字符。所有的JSON的关键字(,,)必须由逗号或其他标点符号所以只有字符串内需要空格分开予以保留。 第一个选项匹配双引号字符串。表示