------------------------------------------------------------------------------
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
------------------------------------------------------------------------------
2. context.xml에서 <Context>태그 부분 수정
------------------------------------------------------------------------------
<Context reloadable="true" privileged="true">
------------------------------------------------------------------------------
** tomcat7.0부터는 servlet3.0을 사용하는 이유로 invoker 기능이 사라졌다.
그래서 찾아보니 그렇게 할 수 있는 java를 만들어 listener로 추가 하는 방법을 구현한 외국분의 사이트를 발견
http://blogs.nologin.es/rickyepoderi/index.php?/archives/44-Tomcat-7-and-the-Invoker-Servlet.html
방법을 정리하자면..
1. InvokerLoadListener.java를 Download
2. web.xml 수정(여기서 말하는 web.xml은 war파일로 묶일 곳의 web.xml, tomcat/conf에 있는 web.xml이 아니다!)
-----------------------------------------------------------------------------
<listener>
<listener-class>
sample.invoker.ctxlistener.InvokerLoadListener
</listener-class>
</listener>
<context-param>
<param-name>invoker.packages</param-name>
<param-value>
sample.invoker.servlet,
sample.invoker.other,
sample.invoker.another
</param-value>
<description>List of packages to check for servlets (comma separated)</description>
</context-param>
-----------------------------------------------------------------------------
고쳐질 web.xml에 대해서 간단한 설명
listener로 지정한 sample.invoker.ctxlistener.InvokerLoadListener
- 당연히 sample.invoker.ctxlistener패키지에 InvokerLoadListener.java를 넣으라는 것
<param-value>안에는 servlet이 들어가 있는 package를 넣을 것(한 개가 아니고 여러개라면 위처럼 ,를 이용해서 구분하자)
블로거의 단점!
왜!! 첨부가 안되는 것이냐.....
혹시나 나중에 링크가 작동안 할 때를 대비한 InvokerLoadListener.java
-----------------------------------------------------------------------------
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package sample.invoker.ctxlistener; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletRegistration; import javax.servlet.http.HttpServlet; import org.apache.catalina.ContainerServlet; /** * * http://snippets.dzone.com/posts/show/4831 * * @author ricky */ public class InvokerLoadListener implements ServletContextListener { /** * Invoker parameter that defines the packages to search servlets. * Comma separated list of packages */ public static final String PACKAGES_PARAMETER = "invoker.packages"; /** * Invoker parameter to setup the mapping name. By default is "/servlet/" */ public static final String INVOKER_PREFIX_PARAMETER = "invoker.prefix"; /** * Scans all classes accessible from the context class loader which * belong to the given package and subpackages. * * @param packageName * @return The list of classes found */ private Set<Class> getClasses(String packageName) { Set<Class> classes = new HashSet<Class>(); try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); if (resource.getProtocol().equals("jar")) { // inside a jar => read the jar files and check findClassesJar(resource, path, classes); } else if (resource.getProtocol().equals("file")) { // read subdirectories and find findClassesFile(new File(resource.getFile()), packageName, classes); } else { System.err.println("Unknown protocol connection: " + resource); } } } catch (IOException e) { e.printStackTrace(); } return classes; } /** * Reads a jar file and checks all the classes inside it with the package * name specified. * * @param resource The resource url * @param path * @param classes * @return */ private Set<Class> findClassesJar(URL resource, String path, Set<Class> classes) { JarURLConnection jarConn = null; JarFile jar = null; try { jarConn = (JarURLConnection) resource.openConnection(); jar = jarConn.getJarFile(); Enumeration<JarEntry> e = jar.entries(); while (e.hasMoreElements()) { JarEntry entry = e.nextElement(); if ((entry.getName().startsWith(path + "/") || entry.getName().startsWith(path + ".")) && entry.getName().endsWith(".class")) { String name = entry.getName().replace('/', '.'); name = name.substring(0, name.length() - 6); checkClass(name, classes); } } } catch (IOException e) { e.printStackTrace(); } finally { try { jar.close(); } catch (IOException e) { } } return classes; } /** * Recursive method used to find all classes in a given file (file * or directory). * * @param file The base directory * @param packageName The package name for classes found inside the base directory * @ classes The list of classes * @return The same classes * @throws ClassNotFoundException */ private Set<Class> findClassesFile(File file, String packageName, Set<Class> classes) { if (file.isFile() && file.getName().endsWith(".class")) { //classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); checkClass(packageName.substring(0, packageName.length() - 6), classes); } else { File[] files = file.listFiles(); for (File f : files) { findClassesFile(f, packageName + "." + f.getName(), classes); } } return classes; } private Set<Class> checkClass(String name, Set<Class> classes) { try { Class clazz = Class.forName(name); if (HttpServlet.class.isAssignableFrom(clazz) && ContainerServlet.class.isAssignableFrom(clazz)) { classes.add(clazz); } } catch (ClassNotFoundException e) { e.printStackTrace(); } return classes; } @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized(ServletContextEvent e)"); ServletContext sc = sce.getServletContext(); String list = sc.getInitParameter(PACKAGES_PARAMETER); String prefix = sc.getInitParameter(INVOKER_PREFIX_PARAMETER); if (prefix == null) { prefix = "/servlet/"; } if (list != null) { String[] packages = list.split(","); for (int i = 0; i < packages.length; i++) { String packageName = packages[i].trim(); if (packageName.length() > 0) { System.out.println("Checking package: " + packageName); // load classes under servlet.invoker Set<Class> classes = getClasses(packageName); System.out.println("size: " + classes.size()); for (Class clazz : classes) { String mapping = prefix + clazz.getName(); System.out.println("Adding '" + clazz.getName() + "' in mapping '" + mapping + "'"); ServletRegistration sr = sc.addServlet(clazz.getName(), clazz.getName()); sr.addMapping(mapping); } } } } } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed(ServletContextEvent e)"); } }-----------------------------------------------------------------------------
war 파일로 묶어서 쓰라는 말씀이신가요?? 제가 완전 초보라 이해를 못하겠어요. web.xml이 수정된 파일과 말씀하신 외국사이트에서 제공하는 파일을 받은 상태예요. 자세히 설명좀 부탁드려도 될까요?????
답글삭제딱 필요한 부분이였는데, 쉬운 설명 감사합니다.
답글삭제딱 필요한 부분이였는데, 쉬운 설명 감사합니다.
답글삭제