1 package de.juplo.thymeproxy;
3 import de.juplo.thymeleaf.JuploDialect;
4 import java.util.HashMap;
5 import java.util.Locale;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9 import org.apache.http.HttpStatus;
10 import org.apache.http.impl.client.CloseableHttpClient;
11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.boot.SpringApplication;
13 import org.springframework.boot.autoconfigure.SpringBootApplication;
14 import org.springframework.boot.autoconfigure.web.BasicErrorController;
15 import org.springframework.boot.autoconfigure.web.ErrorAttributes;
16 import org.springframework.boot.autoconfigure.web.ErrorController;
17 import org.springframework.boot.autoconfigure.web.ErrorProperties;
18 import org.springframework.boot.autoconfigure.web.ServerProperties;
19 import org.springframework.context.annotation.Bean;
20 import org.springframework.core.Ordered;
21 import org.springframework.core.env.Environment;
22 import org.springframework.http.MediaType;
23 import org.springframework.web.servlet.ModelAndView;
24 import org.springframework.web.servlet.View;
25 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
26 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
27 import org.springframework.web.servlet.mvc.UrlFilenameViewController;
28 import org.thymeleaf.exceptions.TemplateInputException;
29 import org.thymeleaf.resourceresolver.IResourceResolver;
30 import org.thymeleaf.resourceresolver.UrlResourceResolver;
31 import org.thymeleaf.spring4.view.ThymeleafViewResolver;
32 import org.thymeleaf.templateresolver.TemplateResolver;
35 @SpringBootApplication
36 public class Application extends WebMvcConfigurerAdapter
39 private ServerProperties properties;
43 public RegexUrlHandlerMapping proxiedHandlerMapping(
44 ProxyHttpRequestHandler proxy,
45 UrlFilenameViewController views
48 RegexUrlHandlerMapping mapping = new RegexUrlHandlerMapping();
49 mapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
50 Map<String, Object> mappings = new HashMap<>();
51 mappings.put("/img/.+", proxy);
52 mappings.put("/css/.+", proxy);
53 mappings.put("/js/.+", proxy);
54 mappings.put("/fonts/.+", proxy);
55 mappings.put("/.*\\.html", views);
56 mapping.setUrlMap(mappings);
61 public ProxyHttpRequestHandler proxyHttpRequestHandler(
62 CloseableHttpClient client,
66 ProxyHttpRequestHandler handler = new ProxyHttpRequestHandler();
67 handler.setClient(client);
68 handler.setOrigin(env.getProperty("thymeproxy.origin"));
69 handler.setTtl(30000l);
74 public UrlFilenameViewController urlFilenameViewController()
76 return new UrlFilenameViewController();
80 public TemplateResolver defaultTemplateResolver(
81 IResourceResolver resources,
85 TemplateResolver resolver = new TemplateResolver();
86 resolver.setResourceResolver(resources);
87 resolver.setPrefix("http://localhost:8080/thymeleaf/");
88 resolver.setSuffix(".html");
89 resolver.setTemplateMode("HTML5");
90 resolver.setCharacterEncoding("UTF-8");
91 resolver.setCacheable(Boolean.valueOf(env.getProperty("thymeproxy.cacheable")));
96 public TemplateResolver jsonTemplateResolver(
97 IResourceResolver resources,
101 TemplateResolver resolver = new TemplateResolver();
102 resolver.setResourceResolver(resources);
103 resolver.setPrefix("http://localhost:8080/thymeleaf/");
104 resolver.setSuffix(".json");
105 resolver.setTemplateMode("JSON");
106 resolver.setCharacterEncoding("UTF-8");
107 resolver.setCacheable(Boolean.valueOf(env.getProperty("thymeproxy.cacheable")));
112 public UrlResourceResolver thymeleafResourceResolver()
114 return new UrlResourceResolver();
118 public JuploDialect juploDialect()
120 return new JuploDialect();
124 public View error(ThymeleafViewResolver resolver) throws Exception
126 return resolver.resolveViewName("templates/500", Locale.getDefault());
130 public ErrorController errorController(ErrorAttributes errorAttributes)
132 return new CustomErrorController(errorAttributes, properties.getError());
137 public void addViewControllers(ViewControllerRegistry registry)
139 registry.addViewController("/").setViewName("forward:index.html");
143 public static void main(String[] args)
145 SpringApplication.run(Application.class, args);
149 static class CustomErrorController extends BasicErrorController
151 public final static String TEMPLATE_INPUT_EXCEPTION =
152 TemplateInputException.class.getCanonicalName();
155 CustomErrorController(
156 ErrorAttributes errorAttributes,
157 ErrorProperties errorProperties
160 super(errorAttributes, errorProperties);
165 public ModelAndView errorHtml(
166 HttpServletRequest request,
167 HttpServletResponse response
170 Map<String, Object> model =
173 isIncludeStackTrace(request, MediaType.TEXT_HTML)
178 switch ((String)model.get("exception"))
180 case "org.thymeleaf.exceptions.TemplateInputException":
181 response.setStatus(HttpStatus.SC_NOT_FOUND);
182 view = "templates/404";
186 response.setStatus(getStatus(request).value());
187 view = "templates/500";
191 return new ModelAndView(view, model);