Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Фильтр сжатия данных, gzip 
:(
    Опции темы
diablero
Дата 27.9.2007, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Народ, как вы сжимаете конечные html  страницы?
Используете готовые решения, если да, то какие или писали свои фильтры? 
Я сейчас пишу свой такой фильтр, и вот задумался, а стоит ли? Может лутше взять готовый?


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
polosatij
Дата 27.9.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 22.2.2004
Где: Stuttgart<-> ;Karlsruhe, Germany

Репутация: 3
Всего: 8





не надо ничего писать..
ты под какой сервер пишешь всё? как правило тебе нужно полазить в конфигурациях веб сервера, поставить что-то типа "труе" и всё  smile 

например, в jboss, файл: server.xml (если мне помять не изменяет)  smile 


--------------------
PM   Вверх
Alexis
Дата 27.9.2007, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 14.8.2006
Где: Казань

Репутация: 5
Всего: 5



Можно и написать. Где-то давно уже стащил, вроде бы из какой-то книги, так и пользуюсь.

Код

package com.domain.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class GZIPFilter implements Filter {
    
    protected static final Log logger = LogFactory.getLog(GZIPFilter.class);

    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
          if (req instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            String ae = request.getHeader("accept-encoding");
            if (ae != null && ae.indexOf("gzip") != -1) {
              logger.debug("GZIP supported, compressing.");
              GZIPResponseWrapper wrappedResponse =
                new GZIPResponseWrapper(response);
              chain.doFilter(req, wrappedResponse);
              wrappedResponse.finishResponse();
              return;
            }
            chain.doFilter(req, res);
          }
        }

        public void init(FilterConfig filterConfig) {
          // noop
        }

        public void destroy() {
          // noop
        }

}


Код

package com.domain.filters;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

public class GZIPResponseStream extends ServletOutputStream {

    // abstraction of the output stream used for compression
    protected OutputStream bufferedOutput = null;

    // state keeping variable for if close() has been called
    protected boolean closed = false;

    // reference to original response
    protected HttpServletResponse response = null;

    // reference to the output stream to the client's browser
    protected ServletOutputStream output = null;

    // default size of the in-memory buffer
    private int bufferSize = 50000;

    public GZIPResponseStream(HttpServletResponse response) throws IOException {
        super();
        closed = false;
        this.response = response;
        this.output = response.getOutputStream();
        bufferedOutput = new ByteArrayOutputStream();
    }

    public void close() throws IOException {
        // This hack shouldn't be needed, but it seems to make JBoss and Struts
        // like the code more without hurting anything.
        /*
         * // verify the stream is yet to be closed if (closed) { throw new
         * IOException("This output stream has already been closed"); }
         */
        // if we buffered everything in memory, gzip it
        if (bufferedOutput instanceof ByteArrayOutputStream) {
            // get the content
            ByteArrayOutputStream baos = (ByteArrayOutputStream) bufferedOutput;
            // prepare a gzip stream
            ByteArrayOutputStream compressedContent = new ByteArrayOutputStream();
            GZIPOutputStream gzipstream = new GZIPOutputStream(
                    compressedContent);
            byte[] bytes = baos.toByteArray();
            gzipstream.write(bytes);
            gzipstream.finish();
            // get the compressed content
            byte[] compressedBytes = compressedContent.toByteArray();
            // set appropriate HTTP headers
            response.setContentLength(compressedBytes.length);
            response.addHeader("Content-Encoding", "gzip");
            output.write(compressedBytes);
            output.flush();
            output.close();
            closed = true;
        }
        // if things were not buffered in memory, finish the GZIP stream and
        // response
        else if (bufferedOutput instanceof GZIPOutputStream) {
            // cast to appropriate type
            GZIPOutputStream gzipstream = (GZIPOutputStream) bufferedOutput;
            // finish the compression
            gzipstream.finish();
            // finish the response
            output.flush();
            output.close();
            closed = true;
        }
    }

    public void flush() throws IOException {
        if (closed) {
            throw new IOException("Cannot flush a closed output stream");
        }
        bufferedOutput.flush();
    }

    public void write(int b) throws IOException {
        if (closed) {
            throw new IOException("Cannot write to a closed output stream");
        }
        // make sure we aren't over the buffer's limit
        checkBufferSize(1);
        // write the byte to the temporary output
        bufferedOutput.write((byte) b);
    }

    private void checkBufferSize(int length) throws IOException {
        // check if we are buffering too large of a file
        if (bufferedOutput instanceof ByteArrayOutputStream) {
            ByteArrayOutputStream baos = (ByteArrayOutputStream) bufferedOutput;
            if (baos.size() + length > bufferSize) {
                // files too large to keep in memory are sent to the client
                // without Content-Length specified
                response.addHeader("Content-Encoding", "gzip");
                // get existing bytes
                byte[] bytes = baos.toByteArray();
                // make new gzip stream using the response output stream
                GZIPOutputStream gzipstream = new GZIPOutputStream(output);
                gzipstream.write(bytes);
                // we are no longer buffering, send content via gzipstream
                bufferedOutput = gzipstream;
            }
        }
    }

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    public void write(byte b[], int off, int len) throws IOException {
        if (closed) {
            throw new IOException("Cannot write to a closed output stream");
        }
        // make sure we aren't over the buffer's limit
        checkBufferSize(len);
        // write the content to the buffer
        bufferedOutput.write(b, off, len);
    }

    public boolean closed() {
        return (this.closed);
    }

    public void reset() {
        // noop
    }

}


Код

package com.domain.filters;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class GZIPResponseWrapper extends HttpServletResponseWrapper {

    protected HttpServletResponse origResponse = null;

    protected ServletOutputStream stream = null;

    protected PrintWriter writer = null;

    public GZIPResponseWrapper(HttpServletResponse response) {
        super(response);
        origResponse = response;
    }

    public ServletOutputStream createOutputStream() throws IOException {
        return (new GZIPResponseStream(origResponse));
    }

    public void finishResponse() {
        try {
            if (writer != null) {
                writer.close();
            } else {
                if (stream != null) {
                    stream.close();
                }
            }
        } catch (IOException e) {
        }
    }

    public void flushBuffer() throws IOException {
        stream.flush();
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (writer != null) {
            throw new IllegalStateException(
                    "getWriter() has already been called!");
        }

        if (stream == null)
            stream = createOutputStream();
        return (stream);
    }

    public PrintWriter getWriter() throws IOException {
        if (writer != null) {
            return (writer);
        }

        if (stream != null) {
            throw new IllegalStateException(
                    "getOutputStream() has already been called!");
        }

        stream = createOutputStream();
        // BUG FIX 2003-12-01 Reuse content's encoding, don't assume UTF-8
        writer = new PrintWriter(new OutputStreamWriter(stream, origResponse
                .getCharacterEncoding()));
        return (writer);
    }

    public void setContentLength(int length) {
    }

}


В web.xml
Код

<filter>
        <filter-name>GZIPFilter</filter-name>
        <filter-class>com.domain.filters.GZIPFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>GZIPFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>


Теоретически должно работать на любом сервере. У меня работает и на Tomcat 5.5 и на Resin 3.0

Это сообщение отредактировал(а) Alexis - 27.9.2007, 18:44
PM   Вверх
polosatij
  Дата 27.9.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 22.2.2004
Где: Stuttgart<-> ;Karlsruhe, Germany

Репутация: 3
Всего: 8




Alexis, не наю.. чисто моё мнение, что это всё ООООЧЕНЬ сильно будет загружать систему... smile


--------------------
PM   Вверх
diablero
Дата 27.9.2007, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Цитата(polosatij @  27.9.2007,  18:26 Найти цитируемый пост)
ты под какой сервер пишешь всё? как правило тебе нужно полазить в конфигурациях веб сервера, поставить что-то типа "труе" и всё

До server.xml не всегда есть доступ.
Нашел почти тоже самое Two Servlet Filters Every Web Application Should Have
Только мне кажется, что как-то кривовато, разбираюсь и правлюsmile


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
diablero
Дата 27.9.2007, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 3.12.2006
Где: Аркхэм

Репутация: 2
Всего: 5



Вот если бы еще знающий человек покритиковал код...
Вот код из статьи, которую я привел выше. Практически тоже самое, что привел и Alexis. Малость исправленный:
Код

public class GZIPFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            if (isGzipSupported(request)) {
                GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper(response);
                filterChain.doFilter(servletRequest, wrappedResponse);
                wrappedResponse.finishResponse();
                return;
            }
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    public void destroy() {

    }
    private boolean isGzipSupported(HttpServletRequest request) {
        String browserEncodings = request.getHeader("Accept-Encoding");
        return ((browserEncodings != null) && (browserEncodings.indexOf("gzip") != -1));
    }
}

Код

public class GZIPResponseStream extends ServletOutputStream {
    protected ByteArrayOutputStream baos;
    protected GZIPOutputStream gzipstream;
    protected HttpServletResponse response;
    protected boolean closed = false;

    public GZIPResponseStream(HttpServletResponse response) throws IOException {
        super();
        closed = false;
        this.response = response;
        baos = new ByteArrayOutputStream();
        gzipstream = new GZIPOutputStream(baos);
    }

    public void close() throws IOException {
        if (closed) {
            throw new IOException("This output stream has already been closed");
        }
        gzipstream.finish();

        byte[] bytes = baos.toByteArray();

        response.setContentLength(bytes.length);
        response.addHeader("Content-Encoding", "gzip");
        
        ServletOutputStream output = response.getOutputStream();
        output.write(bytes);
        output.flush();
        output.close();
        closed = true;
    }

    public void flush() throws IOException {
        if (closed) {
            throw new IOException("Cannot flush a closed output stream");
        }
        gzipstream.flush();
    }

    public void write(int b) throws IOException {
        if (closed) {
            throw new IOException("Cannot write to a closed output stream");
        }
        gzipstream.write((byte) b);
    }

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    public void write(byte b[], int off, int len) throws IOException {
        if (closed) {
            throw new IOException("Cannot write to a closed output stream");
        }
        gzipstream.write(b, off, len);
    }

    public boolean closed() {
        return (this.closed);
    }
}

Код

public class GZIPResponseWrapper extends HttpServletResponseWrapper {
    protected HttpServletResponse httpServletResponse;
    protected ServletOutputStream outputStream;
    protected PrintWriter writer;

    public GZIPResponseWrapper(HttpServletResponse httpServletResponse) {
        super(httpServletResponse);
        this.httpServletResponse = httpServletResponse;
    }

    public ServletOutputStream createOutputStream() throws IOException {
        return (new GZIPResponseStream(httpServletResponse));
    }

    public void finishResponse() throws IOException {
        if (writer != null) writer.close();
        if (outputStream != null) outputStream.close();
    }

    public void flushBuffer() throws IOException {
        outputStream.flush();
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (writer != null) {
            throw new IllegalStateException("getWriter() has already been called!");
        }
        if (outputStream == null) {
            outputStream = createOutputStream();
        }
        return outputStream;
    }

    public PrintWriter getWriter() throws IOException {
        if (outputStream != null) {
            throw new IllegalStateException("getOutputStream() has already been called!");
        }
        if (writer != null) {
            return writer;
        }
        outputStream = createOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, httpServletResponse.getCharacterEncoding()));
        return writer;
    }
}


Это сообщение отредактировал(а) diablero - 27.9.2007, 20:25


--------------------
Есть два варианта решения проблемы - реальный и фантастический. Реальный - это когда прилетят инопланетяне и все за нас сделают ...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0493 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.