Solr是作為一個Servlet運行在Tomcat里面的,可以查看Solr的web.xml。
1.web.xml配置
由web.xml可以看出,基本上所有Solr的操作都是在SolrDispatchFilter中實現的。當輸入http://localhost:8080/solr/前綴的URL就會觸發SolrDispatchFilter.
1 <filter> 2 <filter-name>SolrRequestFilter</filter-name> 3 <filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class> 4 <init-param> 5 <param-name>path-prefix</param-name> 6 <param-value>/xxx</param-value> 7 </init-param> 8 </filter> 9 10 <filter-mapping> 11 <filter-name>SolrRequestFilter</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping> 14 <servlet> 15 <servlet-name>RedirectOldAdminUI</servlet-name> 16 <servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class> 17 <init-param> 18 <param-name>destination</param-name> 19 <param-value>${context}/#/</param-value> 20 </init-param> 21 </servlet> 22 <servlet-mapping> 23 <servlet-name>RedirectOldAdminUI</servlet-name> 24 <url-pattern>/admin/</url-pattern> 25 </servlet-mapping>
2. SolrDispatchFilter的實現
SolrDispatchFilter繼承了Filter,實現主要分為三個接口:init,dofilter,destory。其中init和destory分別在tomcat的啟動和關閉時候進行。
1 /** 2 *初始化,當tomcat啟動時候開始初始化,其中主要調用createCoreContainer來實現Solr的初始化 3 */ 4 public void init(FilterConfig config) throws ServletException 5 { 6 log.info("SolrDispatchFilter.init()"); 7 8 try { 9 // web.xml configuration 10 this.pathPrefix = config.getInitParameter( "path-prefix" ); 11 12 this.cores = createCoreContainer(); 13 log.info("user.dir=" + System.getProperty("user.dir")); 14 } 15 catch( Throwable t ) { 16 // catch this so our filter still works 17 log.error( "Could not start Solr. Check solr/home property and the logs"); 18 SolrCore.log( t ); 19 if (t instanceof Error) { 20 throw (Error) t; 21 } 22 } 23 24 log.info("SolrDispatchFilter.init() done"); 25 } 26 /** 27 * filter接口的具體實現,這里主要實現了主要的Solr功能 28 */ 29 @Override 30 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 31 doFilter(request, response, chain, false); 32 } 33 34 /** 35 * 關閉Solr 36 */ 37 @Override 38 public void destroy() { 39 if (cores != null) { 40 cores.shutdown(); 41 cores = null; 42 } 43 } 44 }
3.Servlet的實現
通過查看web.xml以及源碼可以看到,雖然Solr繼承並實現了Servlet接口,但是Solr的主要操作卻是主要集中在dofilter里面。以RedictServlet為例,它主要實現了http的重定向功能。從web.xml配置中可以看到,當url為solr/admin時候就會重定向為solr/#/
1 /** 2 * A Simple redirection servlet to help us deprecate old UI elements 3 */ 4 public class RedirectServlet extends BaseSolrServlet { 5 6 static final String CONTEXT_KEY = "${context}"; 7 8 String destination; 9 int code = HttpServletResponse.SC_MOVED_PERMANENTLY; 10 11 @Override 12 public void init(ServletConfig config) throws ServletException { 13 super.init(config); 14 15 destination = config.getInitParameter("destination"); 16 if(destination==null) { 17 throw new ServletException("RedirectServlet missing destination configuration"); 18 } 19 if( "false".equals(config.getInitParameter("permanent") )) { 20 code = HttpServletResponse.SC_MOVED_TEMPORARILY; 21 } 22 // 獲取重定向的url 解析init-param 獲取destination值 23 // Replace the context key 24 if(destination.startsWith(CONTEXT_KEY)) { 25 destination = config.getServletContext().getContextPath() 26 +destination.substring(CONTEXT_KEY.length()); 27 } 28 } 29 30 @Override 31 public void doGet(HttpServletRequest req, HttpServletResponse res) 32 throws ServletException,IOException { 33 34 res.setStatus(code); 35 res.setHeader("Location", destination); 36 } 37 38 }