[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-a-brief-look-at-the-rewrite-valve-in-tomcat-8":3},{"id":4,"title":5,"body":6,"date":438,"description":12,"extension":373,"meta":439,"navigation":172,"path":440,"published":172,"seo":441,"slug":442,"stem":443,"summary":5,"tags":444,"__hash__":448},"blog/blog/2015-09-11-a-brief-look-at-the-rewrite-valve-in-tomcat-8.md","A Brief Look at the Rewrite Valve in Tomcat 8",{"type":7,"value":8,"toc":435},"minimark",[9,13,18,29,60,65,70,249,253,259,359,363,366,369,404,407,421,428,431],[10,11,12],"p",{},"Recently I learned that Tomcat 8 has its own built in approach to handling URL rewriting to achieve things like SES (pretty) URLs. Personally I do URL rewrites from Nginx, as it's the forward facing web server and proxy to all of my Lucee apps that live in Tomcat; but, for the sake of learning, I wanted to take a look at what it had to offer.",[14,15,17],"h2",{"id":16},"setting-it-up","Setting it up...",[10,19,20,21,28],{},"Reading through the ",[22,23,27],"a",{"href":24,"rel":25},"http://tomcat.apache.org/tomcat-8.0-doc/rewrite.html",[26],"nofollow","Tomcat 8 Rewrite Docs",", I was delighted to see that they use a similar approach to syntax as Apache's Mod_Rewrite so the learning curve of writing actual rewrites is minimal to anyone who's worked with Apache in the past.",[10,30,31,32,36,37,40,41,44,45,48,49,52,53,56,57,59],{},"Essentially, all you need to do is include the rewrite valve class ",[33,34,35],"code",{},"org.apache.catalina.valves.rewrite.RewriteValve"," in your application's context. This can be either the global context.xml or in the context block of a host in the ",[33,38,39],{},"server.xml","; both found in Tomcat's ",[33,42,43],{},"/conf"," directory. Then drop a ",[33,46,47],{},"rewrite.config"," file containing your rewrites into the WEB-INF folder of ROOT or wherever your application's root ",[33,50,51],{},"WEB-INF"," is. Using the global ",[33,54,55],{},"context.xml"," will effect all virtual host setups you've defined in your ",[33,58,39],{}," so if you have multiple apps running, it may be best to do a per host setup of the rewrite valve.",[61,62,64],"h4",{"id":63},"the-global-approach","The global approach:",[10,66,67,68],{},"Here's an example of setting the valve in Tomcat's ",[33,69,55],{},[71,72,77],"pre",{"className":73,"code":74,"language":75,"meta":76,"style":76},"language-xml shiki shiki-themes github-light github-dark github-dark monokai","\u003C?xml version='1.0' encoding='utf-8'?>\n\u003C!-- The contents of this file will be loaded for each web application -->\n\u003CContext>\n    \u003C!-- REWRITE VALVE -->\n    \u003CValve className=\"org.apache.catalina.valves.rewrite.RewriteValve\" />\n    \u003C!-- // -->\n\n    \u003C!-- Speed up context loading -->\n    \u003CJarScanner scanClassPath=\"false\" />\n    \u003C!-- Default set of monitored resources. If one of these changes, the -->\n    \u003C!-- web application will be reloaded.                                -->\n    \u003CWatchedResource>WEB-INF/web.xml\u003C/WatchedResource>\n    \u003CWatchedResource>${catalina.base}/conf/web.xml\u003C/WatchedResource>\n\u003C/Context>\n","xml","",[33,78,79,113,120,132,138,158,167,174,180,198,204,210,225,239],{"__ignoreMap":76},[80,81,84,88,91,95,98,102,105,107,110],"span",{"class":82,"line":83},"line",1,[80,85,87],{"class":86},"s__4a","\u003C?",[80,89,75],{"class":90},"sIn_X",[80,92,94],{"class":93},"s9ihy"," version",[80,96,97],{"class":86},"=",[80,99,101],{"class":100},"svw4x","'1.0'",[80,103,104],{"class":93}," encoding",[80,106,97],{"class":86},[80,108,109],{"class":100},"'utf-8'",[80,111,112],{"class":86},"?>\n",[80,114,116],{"class":82,"line":115},2,[80,117,119],{"class":118},"sq-8i","\u003C!-- The contents of this file will be loaded for each web application -->\n",[80,121,123,126,129],{"class":82,"line":122},3,[80,124,125],{"class":86},"\u003C",[80,127,128],{"class":90},"Context",[80,130,131],{"class":86},">\n",[80,133,135],{"class":82,"line":134},4,[80,136,137],{"class":118},"    \u003C!-- REWRITE VALVE -->\n",[80,139,141,144,147,150,152,155],{"class":82,"line":140},5,[80,142,143],{"class":86},"    \u003C",[80,145,146],{"class":90},"Valve",[80,148,149],{"class":93}," className",[80,151,97],{"class":86},[80,153,154],{"class":100},"\"org.apache.catalina.valves.rewrite.RewriteValve\"",[80,156,157],{"class":86}," />\n",[80,159,161,164],{"class":82,"line":160},6,[80,162,163],{"class":118},"    \u003C!--",[80,165,166],{"class":118}," // -->\n",[80,168,170],{"class":82,"line":169},7,[80,171,173],{"emptyLinePlaceholder":172},true,"\n",[80,175,177],{"class":82,"line":176},8,[80,178,179],{"class":118},"    \u003C!-- Speed up context loading -->\n",[80,181,183,185,188,191,193,196],{"class":82,"line":182},9,[80,184,143],{"class":86},[80,186,187],{"class":90},"JarScanner",[80,189,190],{"class":93}," scanClassPath",[80,192,97],{"class":86},[80,194,195],{"class":100},"\"false\"",[80,197,157],{"class":86},[80,199,201],{"class":82,"line":200},10,[80,202,203],{"class":118},"    \u003C!-- Default set of monitored resources. If one of these changes, the -->\n",[80,205,207],{"class":82,"line":206},11,[80,208,209],{"class":118},"    \u003C!-- web application will be reloaded.                                -->\n",[80,211,213,215,218,221,223],{"class":82,"line":212},12,[80,214,143],{"class":86},[80,216,217],{"class":90},"WatchedResource",[80,219,220],{"class":86},">WEB-INF/web.xml\u003C/",[80,222,217],{"class":90},[80,224,131],{"class":86},[80,226,228,230,232,235,237],{"class":82,"line":227},13,[80,229,143],{"class":86},[80,231,217],{"class":90},[80,233,234],{"class":86},">${catalina.base}/conf/web.xml\u003C/",[80,236,217],{"class":90},[80,238,131],{"class":86},[80,240,242,245,247],{"class":82,"line":241},14,[80,243,244],{"class":86},"\u003C/",[80,246,128],{"class":90},[80,248,131],{"class":86},[61,250,252],{"id":251},"the-individual-host-approach","The individual host approach:",[10,254,255,256,258],{},"In my case with running multiple Lucee applications through Tomcat, I would want to set up the rewrites per host. Here's an example of a host block in the ",[33,257,39],{},".",[71,260,262],{"className":73,"code":261,"language":75,"meta":76,"style":76},"\u003CHost name=\"tonyjunkes.com\" appBase=\"webapps\" unpackWARs=\"false\" autoDeploy=\"false\">\n  \u003CContext path=\"\" docBase=\"C:/websites/tonyjunkes/www\">\n    \u003CValve className=\"org.apache.catalina.valves.rewrite.RewriteValve\" />\n  \u003C/Context>\n\u003C/Host>\n",[33,263,264,303,328,342,351],{"__ignoreMap":76},[80,265,266,268,271,274,276,279,282,284,287,290,292,294,297,299,301],{"class":82,"line":83},[80,267,125],{"class":86},[80,269,270],{"class":90},"Host",[80,272,273],{"class":93}," name",[80,275,97],{"class":86},[80,277,278],{"class":100},"\"tonyjunkes.com\"",[80,280,281],{"class":93}," appBase",[80,283,97],{"class":86},[80,285,286],{"class":100},"\"webapps\"",[80,288,289],{"class":93}," unpackWARs",[80,291,97],{"class":86},[80,293,195],{"class":100},[80,295,296],{"class":93}," autoDeploy",[80,298,97],{"class":86},[80,300,195],{"class":100},[80,302,131],{"class":86},[80,304,305,308,310,313,315,318,321,323,326],{"class":82,"line":115},[80,306,307],{"class":86},"  \u003C",[80,309,128],{"class":90},[80,311,312],{"class":93}," path",[80,314,97],{"class":86},[80,316,317],{"class":100},"\"\"",[80,319,320],{"class":93}," docBase",[80,322,97],{"class":86},[80,324,325],{"class":100},"\"C:/websites/tonyjunkes/www\"",[80,327,131],{"class":86},[80,329,330,332,334,336,338,340],{"class":82,"line":122},[80,331,143],{"class":86},[80,333,146],{"class":90},[80,335,149],{"class":93},[80,337,97],{"class":86},[80,339,154],{"class":100},[80,341,157],{"class":86},[80,343,344,347,349],{"class":82,"line":134},[80,345,346],{"class":86},"  \u003C/",[80,348,128],{"class":90},[80,350,131],{"class":86},[80,352,353,355,357],{"class":82,"line":140},[80,354,244],{"class":86},[80,356,270],{"class":90},[80,358,131],{"class":86},[61,360,362],{"id":361},"making-it-all-happen-with-rewriteconfig","Making it all happen with rewrite.config",[10,364,365],{},"If you're running your application from the base ROOT of Tomcat or are using a global rewrite to effect all virtual hosts, then you can drop your rewrite.config right into the WEB-INF there. Otherwise you will need to locate the WEB-INF of your application. In the case of my Lucee apps, the WEB-INF will be in my application's web root.",[10,367,368],{},"Here's an example rewrite.config that rewrites the URL to exclude index.cfm.",[71,370,374],{"className":371,"code":372,"language":373,"meta":76,"style":76},"language-md shiki shiki-themes github-light github-dark github-dark monokai","RewriteCond %{REQUEST*URI} !^.*\\.(bmp|css|gif|htc|html?|ico|jpe?g|js|pdf|png|swf|txt|xml|svg|eot|woff|woff2|ttf)$\nRewriteRule ^(._)$ index.cfm/$1 [L]\n","md",[33,375,376,392],{"__ignoreMap":76},[80,377,378,381,385,389],{"class":82,"line":83},[80,379,380],{"class":86},"RewriteCond %{REQUEST",[80,382,384],{"class":383},"sjnEG","*URI} !^.*",[80,386,388],{"class":387},"s-7EV","\\.",[80,390,391],{"class":86},"(bmp|css|gif|htc|html?|ico|jpe?g|js|pdf|png|swf|txt|xml|svg|eot|woff|woff2|ttf)$\n",[80,393,394,397,401],{"class":82,"line":115},[80,395,396],{"class":86},"RewriteRule ^(._)$ index.cfm/$1 [",[80,398,400],{"class":399},"smDfC","L",[80,402,403],{"class":86},"]\n",[10,405,406],{},"There we have it. Nice and simple. I haven't done much else with it at this point so I'm not aware of any major caveats with intricate rewrites.",[10,408,409,414,415,420],{},[22,410,413],{"href":411,"rel":412},"https://www.webucator.com/",[26],"Webucator",", a provider of ",[22,416,419],{"href":417,"rel":418},"https://www.webucator.com/servers/tomcat.cfm",[26],"Tomcat Online and Onsite Training Classes",", has produced a video demonstrating the use of Tomcat's Rewrite Valve as I've explained above.",[422,423],"iframe",{"width":424,"height":425,"src":426,"frameBorder":427,"allowFullScreen":172},560,315,"https://www.youtube.com/embed/ZjyhvLyHZfI","0",[10,429,430],{},"Cheers and happy coding!",[432,433,434],"style",{},"html pre.shiki code .s__4a, html code.shiki .s__4a{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sIn_X, html code.shiki .sIn_X{--shiki-light:#22863A;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .s9ihy, html code.shiki .s9ihy{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .svw4x, html code.shiki .svw4x{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sq-8i, html code.shiki .sq-8i{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-sepia:#88846F}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sjnEG, html code.shiki .sjnEG{--shiki-light:#24292E;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s-7EV, html code.shiki .s-7EV{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .smDfC, html code.shiki .smDfC{--shiki-light:#032F62;--shiki-light-text-decoration:underline;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}",{"title":76,"searchDepth":115,"depth":115,"links":436},[437],{"id":16,"depth":115,"text":17},"2015-09-11",{},"/blog/2015-09-11-a-brief-look-at-the-rewrite-valve-in-tomcat-8",{"title":5,"description":12},"a-brief-look-at-the-rewrite-valve-in-tomcat-8","blog/2015-09-11-a-brief-look-at-the-rewrite-valve-in-tomcat-8",[445,446,447],"Lucee","Apache Tomcat","URL Rewrites","D9yOsp-l151an3AUkxzWGPoVDfAS6PL2_S8w5i7aLF4"]