func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {
	if !c.doNotRecover {  
		defer func() {
			if r := recover(); r != nil {
				c.recoverHandleFunc(r, httpWriter)
				return
			}
		}()
	}
	defer func() {
		if nil != httpRequest.Body {
			httpRequest.Body.Close()
		}
	}()
	writer := httpWriter
	if c.contentEncodingEnabled {
		doCompress, encoding := wantsCompressedResponse(httpRequest)
		if doCompress {
			var err error
			writer, err = NewCompressingResponseWriter(httpWriter, encoding)
			if err != nil {
				log.Println("[restful] unable to install compressor:", err)
				httpWriter.WriteHeader(http.StatusInternalServerError)
				return
			}
			defer func() {
				writer.(*CompressingResponseWriter).Close()
			}()
		}
	}
	webService, route, err := c.router.SelectRoute(
		c.webServices,
		httpRequest)
	if err != nil {
		chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
			switch err.(type) {
			case ServiceError:
				ser := err.(ServiceError)
				resp.WriteErrorString(ser.Code, ser.Message)
			}
		}}
		chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))
		return
	}
	wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest)
	if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 {
		allFilters := []FilterFunction{}
		allFilters = append(allFilters, c.containerFilters...)
		allFilters = append(allFilters, webService.filters...)
		allFilters = append(allFilters, route.Filters...)
		chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) {
			route.Function(wrappedRequest, wrappedResponse)
		}}
		chain.ProcessFilter(wrappedRequest, wrappedResponse)
	} else {
		route.Function(wrappedRequest, wrappedResponse)
	}
}
Dispatch the incoming Http Request to a matching WebService.
package restful
import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"runtime"
	"strings"
)
type Container struct {
	webServices            []*WebService
	ServeMux               *http.ServeMux
	isRegisteredOnRoot     bool
	containerFilters       []FilterFunction
	doNotRecover           bool  
	recoverHandleFunc      RecoverHandleFunction
	router                 RouteSelector  
	contentEncodingEnabled bool           
}
func NewContainer() *Container {
	return &Container{
		webServices:            []*WebService{},
		ServeMux:               http.NewServeMux(),
		isRegisteredOnRoot:     false,
		containerFilters:       []FilterFunction{},
		doNotRecover:           false,
		recoverHandleFunc:      logStackOnRecover,
		router:                 RouterJSR311{},
		contentEncodingEnabled: false}
}
type RecoverHandleFunction func(interface{}, http.ResponseWriter)
func (c *Container) RecoverHandler(handler RecoverHandleFunction) {
	c.recoverHandleFunc = handler
}
func (c *Container) DoNotRecover(doNot bool) {
	c.doNotRecover = doNot
}
func (c *Container) Router(aRouter RouteSelector) {
	c.router = aRouter
}
func (c *Container) EnableContentEncoding(enabled bool) {
	c.contentEncodingEnabled = enabled
}
func (c *Container) Add(service *WebService) *Container {
	if !c.isRegisteredOnRoot {
		pattern := c.fixedPrefixPath(service.RootPath())
		if "/" == pattern || "" == pattern {
			c.ServeMux.HandleFunc("/", c.dispatch)
			c.isRegisteredOnRoot = true
		} else {
			alreadyMapped := false
			for _, each := range c.webServices {
				if each.RootPath() == service.RootPath() {
					alreadyMapped = true
					break
				}
			}
			if !alreadyMapped {
				c.ServeMux.HandleFunc(pattern, c.dispatch)
				if !strings.HasSuffix(pattern, "/") {
					c.ServeMux.HandleFunc(pattern+"/", c.dispatch)
				}
			}
		}
	}
	for _, each := range c.webServices {
		if each.RootPath() == service.RootPath() {
			log.Fatalf("[restful] WebService with duplicate root path detected:['%v']", each)
		}
	}
	if len(service.rootPath) == 0 {
		service.Path("/")
	}
	c.webServices = append(c.webServices, service)
	return c
}
func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) {
	var buffer bytes.Buffer
	buffer.WriteString(fmt.Sprintf("[restful] recover from panic situation: - %v\r\n", panicReason))
	for i := 2; ; i += 1 {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		buffer.WriteString(fmt.Sprintf("    %s:%d\r\n", file, line))
	}
	log.Println(buffer.String())
	httpWriter.WriteHeader(http.StatusInternalServerError)
	httpWriter.Write(buffer.Bytes())
}