001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.isis.core.webapp.routing; 020 021import java.io.IOException; 022 023import javax.servlet.Filter; 024import javax.servlet.FilterChain; 025import javax.servlet.FilterConfig; 026import javax.servlet.ServletException; 027import javax.servlet.ServletRequest; 028import javax.servlet.ServletResponse; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035/** 036 * This filter attempts to ensure that would-be users of the framework are 037 * directed to the bundled documentation, rather than just hitting the REST API 038 * (ie the json viewer). 039 * 040 * <p> 041 * Specifically, if the request is to "/" but the Accept header is anything 042 * other than "application/json" (eg is set to "text/html" and suggesting that 043 * the user is using a browser to access the webapp) then the filter redirects 044 * to /index.html (the documentation pages). 045 * 046 * <p> 047 * Only if the Accept header is set to application/json is the request allowed 048 * to continue through. 049 */ 050public class RedirectToDocsFilter implements Filter { 051 052 private static final Logger LOG = LoggerFactory.getLogger(RedirectToDocsFilter.class); 053 054 private static final String REDIRECT_TO_KEY = "redirectTo"; 055 private static final String REDIRECT_TO_DEFAULT = "/index.html"; 056 057 private static final String ACCEPT_HEADER = "Accept"; 058 private static final String APPLICATION_JSON_MIME_TYPE = "application/json"; 059 060 private String redirectTo; 061 062 @Override 063 public void init(final FilterConfig cfg) throws ServletException { 064 redirectTo = cfg.getInitParameter(REDIRECT_TO_KEY); 065 if (redirectTo == null) { 066 redirectTo = REDIRECT_TO_DEFAULT; 067 } 068 System.out.println("redirectToDocsFilter: redirectTo=" + redirectTo); 069 LOG.info("redirectToDocsFilter: redirectTo=" + redirectTo); 070 } 071 072 @Override 073 public void destroy() { 074 } 075 076 @Override 077 public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { 078 final HttpServletRequest httpServletRequest = (HttpServletRequest) request; 079 final HttpServletResponse httpServletResponse = (HttpServletResponse) response; 080 081 // do nothing if not requesting "/" 082 final String servletPath = httpServletRequest.getServletPath(); 083 System.out.println("redirectToDocsFilter: servletPath: " + servletPath); 084 LOG.info("redirectToDocsFilter: servletPath: " + servletPath); 085 086 if (!"/".equals(servletPath)) { 087 chain.doFilter(request, response); 088 return; 089 } 090 091 final String acceptHeader = httpServletRequest.getHeader(ACCEPT_HEADER); 092 if (acceptHeader != null && acceptHeader.startsWith(APPLICATION_JSON_MIME_TYPE)) { 093 // let request through 094 chain.doFilter(request, response); 095 return; 096 } 097 098 // otherwise redirect 099 final String redirect = combine(httpServletRequest.getContextPath(), redirectTo); 100 System.out.println("redirectToDocsFilter: redirecting to: " + redirect); 101 LOG.info("redirectToDocsFilter: redirecting to: " + redirect); 102 103 httpServletResponse.sendRedirect(redirect); 104 } 105 106 private static String combine(final String str1, final String str2) { 107 final StringBuilder buf = new StringBuilder(str1); 108 if (!str2.startsWith("/")) { 109 buf.append("/"); 110 } 111 buf.append(str2); 112 return buf.toString(); 113 } 114 115}