2015-02-09 3 views
1

Я написал инструмент, который обертывает http.ResponseWriter и предоставляет новый метод визуализации шаблона.Как реализовать метод перезаписи интерфейса

type MyResponseWriter interface { 
     http.ResponseWriter 
     Render(tmpl string, v interface{} 
} 
type myResponseWriter struct { 
    server *Server 
    http.ResponseWriter 
} 

func (rw *myResponseWriter) Render(tmpl string, v interface{}) { 
     rw.server.Render(rw, tmpl, v) 
} 

Теперь я хочу, чтобы переопределить метод WriteMyResponseWriter «s, чтобы включить сжатие GZIP в качестве сменного фильтра, не зная реализации MyResponseWriter.

Я написал GzipResponseWriter здесь, и он используется в качестве MyResponseWriter, так что подключаемый:

type GzipResponseWriter struct { 
    MyResponseWriter 
} 

func (grw *GzipResponseWriter) Write(data []byte) (int, error) { 
     return GzipWrite(grw.MyResponseWriter, data)  
} 

Но, когда я включаю GzipResponseWriter затем вызвать Render, он до сих пор называет MyResponseWriter «s Write, а не GzipResponseWriter , и браузер показывают мне «Ошибка кодирования содержимого».

Это все из-за того, когда я называю Render из GzipResponseWriter, реального метода приемник по-прежнему myResponseWriter и Render вызовов myResponseWriter «ы Write.

Я думаю, что это обычное требование, что мы вносим изменения в некоторые методы интерфейса, которые поставляются с библиотеками/фреймами, а другие методы этого интерфейса будут вызывать эти новые методы, а не старые методы. В моем вопросе требование - сжатие gzip, но эту функцию так сложно реализовать в Go.

Есть ли решение для реализации этого предложения? Спасибо.

+0

Я предполагаю, что вы хотели написать 'тип интерфейса GzipResponseWriter {' (отсутствует ключевое слово 'interface') ... – icza

+0

Спасибо. Это структура. – cosiner

+0

Ну, что меняет картину, мне пришлось переписать свой ответ. – icza

ответ

0

Добавить новое поле out io.Writer к myResponseWriter, а также добавить метод io.Write(), который использует этот out поле:

type myResponseWriter struct { 
    out io.Writer 
    server *Server 
    http.ResponseWriter 
} 

func (m *myResponseWriter) Write(b []byte) (int, error) { 
    return m.out.Write(b) 
} 

И по умолчанию установлен тот же http.ResponseWriter в out поле тоже.

И когда вы хотите переключиться на ответ с gzip'нутым, просто обернуть out писатель так:

out = gzip.NewWriter(out) 

С myResponseWriter.Write() устройства используется out поля, ваш метод Render() пошлет свой выход через GZIP писатель.

+0

Но если я назову 'Render' на' myGzipResponseWriter', который вызывает 'Write', реальный приемник метода' Write' по-прежнему остается 'myResonseWriter', а не' myGzipResonseWriter', поэтому 'GzipWrite' не будет вызываться. – cosiner

+0

Извините, это все еще не мое желание, если я хочу включить gzip, я должен добавить метод для изменения 'out' в поле' MyResponseWriter'. – cosiner

Смежные вопросы