Java tutorial
/** * Copyright 2012 the project-owners * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package inti.ws.spring.resource; import inti.util.DateFormatter; import inti.ws.spring.exception.client.NotFoundException; import inti.ws.spring.resource.config.ConfigParserSettings; import inti.ws.spring.resource.config.ResourceConfig; import inti.ws.spring.resource.config.ResourceConfigProvider; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpHeaders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class ResourceController { private static final Logger LOGGER = LoggerFactory.getLogger(ResourceController.class); private static final String EXPIRES_IMMEDIATELY = "-1"; @Inject ResourceConfigProvider configProvider; @Inject ServletContext ctx; ThreadLocal<ResourceWorkingContext> contexts = new ThreadLocal<ResourceWorkingContext>() { @Override protected ResourceWorkingContext initialValue() { return new ResourceWorkingContext(); } }; DateFormatter dateFormatter = new DateFormatter(); PathMatcher pathMatcher = new AntPathMatcher(); protected void applyCachingHeader(HttpServletResponse response, WebResource resource, ConfigParserSettings settings) { ResourceWorkingContext ctx = contexts.get(); if (settings != null) { if (settings.getExpires() > 0) { // http://en.wikipedia.org/wiki/List_of_HTTP_header_fields ctx.clearBuilder(); dateFormatter.formatDate(System.currentTimeMillis() + settings.getExpires(), ctx.getBuilder()); response.addHeader(HttpHeaders.EXPIRES, ctx.getBuilder().toString()); if (resource.getMessageDigest() != null) { response.setHeader(HttpHeaders.ETAG, resource.getMessageDigest()); } if (resource.getLastModifiedString() != null) { response.setHeader(HttpHeaders.LAST_MODIFIED, resource.getLastModifiedString()); } } else { response.addHeader(HttpHeaders.EXPIRES, EXPIRES_IMMEDIATELY); } if (settings.getCacheControl() != null) { response.setHeader(HttpHeaders.CACHE_CONTROL, settings.getCacheControl()); } } } protected void resource(String name, WebResource resource, HttpServletRequest request, HttpServletResponse response, ConfigParserSettings settings) throws Exception { String tmp; resource.updateIfNeeded(); if ((tmp = request.getHeader(HttpHeaders.IF_MODIFIED_SINCE)) != null) { if (resource.getLastModified() <= dateFormatter.parseDate(tmp)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } } else if ((tmp = request.getHeader(HttpHeaders.IF_NONE_MATCH)) != null) { if (tmp.equals(resource.getMessageDigest())) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } } if (settings != null) { try { applyCachingHeader(response, resource, settings); } catch (Exception exception) { LOGGER.debug("", exception); } if (settings.getContentType() != null) { response.setHeader(HttpHeaders.CONTENT_TYPE, settings.getContentType()); } if (settings.getContentEncoding() != null) { response.setHeader(HttpHeaders.CONTENT_ENCODING, settings.getContentEncoding()); } try { resource.processResponse(request, response, settings); } catch (Exception exception) { LOGGER.debug("", exception); } byte[] data = resource.getByteContent(settings); if (data != null) { response.getOutputStream().write(data); response.getOutputStream().close(); } } } @RequestMapping(value = "/**/*.*", method = RequestMethod.GET) public void resource(HttpServletRequest request, HttpServletResponse response) throws Exception { String uri = request.getRequestURI(); List<ResourceConfig> configs = configProvider.getResourceConfigs(request); if (!ctx.getContextPath().equals("")) { uri = uri.replaceFirst(ctx.getContextPath(), ""); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("resource - handling request for uri={}", uri); LOGGER.debug("resource - searching in={}", configs); } if (configs != null) { for (ResourceConfig config : configs) { for (Map.Entry<String, ? extends WebResource> resource : config.getResources().entrySet()) { WebResource webResource = resource.getValue(); if (webResource.getRoute() != null && pathMatcher.match(webResource.getRoute(), uri)) { LOGGER.debug("resource - resource found for uri={}", uri); resource(resource.getKey(), resource.getValue(), request, response, config.getSettings()); return; } } } } throw new NotFoundException("resource not found: " + uri); } }