JBoss AS의 web에는 tomcat이 빌드되어 있습니다. Servlet을 호출할 경우 보통 org.apache.catalina.servlets.InvokerServlet을 사용하여 다음과 같은 URL을 사용하여 직접 서블릿 클래스를 호출하는 것이 가능합니다.
As you may know, JBoss Appliation Server includes tomcat runtime for processing web application. If you don't want to use specific url-pattern in web descriptor file(web.xml), you can use Tomcat invoker servlet instead of it.
Assume that we have a web application like this :
source : info.javapattern.servlet.TestServlet
war context : test

web.xml


<servlet>
    <servlet-name>invoker</servlet-name>
    <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</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>


위와 같은 설정이 되어 있을 경우 해당 컨텍스트의 서블릿 클래스는 다음과 같이 호출됩니다.
It is possible to access an written servlet class by name through the invoker as follow:

http://ip:port/context/invoker-url-pattern/pacakge.ServletClass

이를 실제 URL로 위의 예를 변환하면
http://localhost:8080/test/servlet/info.javapattern.servlet.TestServlet

놀새~에게 나타났던 문제는 "고객사에서 /servlet/info.javapattern.servlet.TestServlet 처럼 호출이 아닌 WebLogic, Jeus(초기에 웹로직을 본떴으니 같은 기능을 가지고 있겠죠)와 같은 /servlet/info/javapattern/servlet/TestServlet 호출시 해당 서블릿이 구동되게 해주십시오"였습니다.

이를 해결하기 위해 catalina 소스를 빌드하였지만 컨텍스트 클래스 로더 내의 클래스로 한정짓는 제약조건과 signing된 jar로 인하여 소스를 패치하는 것에 문제가 있었습니다.
결국 이를 해결하기 위해 InvokerServlet을 사용하는 중간 단계의 서블릿을 하나 만들어 Catalina InvokerServlet으로 전달하는 방식으로 Slash 형태의 서블릿을 호출하는 코드를 만들었습니다.
SlashInvoker의 소스는 다음과 같습니다.

I've got a customer who is asking JBoss web container can be invoked using slash style url pattern like WebLogic. To resolve this issue, I made a patch by changing the catalina source(InvokerServlet), but it failed because there was a problems with ServletDispatcher.
Finally, I made a temporary servlet to redirect request to catalina InvokerServlet. It is called SlashInvoker and its code is here :


package org.jboss.servlets;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.logging.Logger;

public class SlashInvoker extends HttpServlet {

	private static final long serialVersionUID = 156894170597729161L;
	private int debug = 0;
	private static Logger log = Logger.getLogger(SlashInvoker.class);

	/** A serialized MarshalledInvocation */

	/**
	 * Initializes the servlet.
	 */
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		try {
			// Set our properties from the initialization parameters
			if (getServletConfig().getInitParameter("debug") != null)
				debug = Integer.parseInt(getServletConfig().getInitParameter("debug"));

		} catch (Exception e) {
			throw new ServletException("Failed to build invokerName", e);
		}

	}

	/**
	 * Destroys the servlet.
	 */
	@Override
	public void destroy() {

	}

	/**
	 * Handles the HTTP <code>GET</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * Handles the HTTP <code>POST</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * Returns a short description of the servlet.
	 */
	@Override
	public String getServletInfo() {
		return "An HTTP to JMX invocation servlet";
	}

	/**
	 * Process servlet request using slash url pattern
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		try {
			if( debug > 0 ) {
				log.info("************ URI : " + request.getRequestURI());
				log.info("************ PATH INFO : " + request.getPathInfo());
			}
			String servletClass = request.getPathInfo();
			int slash = servletClass.indexOf('/');
			if (slash >= 0) {
				servletClass = servletClass.substring(slash + 1);
			}

			String inServletClass = servletClass.replace("/", ".");

			String redirectUrl = request.getContextPath() + "/catalina/"
					+ inServletClass;
			if( debug > 0 ) 
				log.info("************* Redirect URL : " + redirectUrl);

			// response.sendRedirect(redirectUrl);
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher("/catalina/" + inServletClass);
			dispatcher.forward(request, response);

		} catch (Exception e) {
			throw new ServletException("Failed to build invokerName", e);
		}
	}
}


이 Invoker를 사용하는 web.xml에서는 invoker를 /servlet/*로 변경하고 해당 URL pattern으로 들어오는 서블릿의 경로를 /에서 .으로 변경한 후 실제 catalina의 invoker로 redirect시키는 방법으로 문제를 해결하였습니다.


I fixed the problem by changing servlet path information from slash(/) to dot(.) and redirecting to catalina servlet. The descriptor I explained is below:


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>jboss-jms-monitor</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>invoker</servlet-name>
    <servlet-class>
          org.jboss.servlets.SlashInvoker
        </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>invoker</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>CatalinaInvoker</servlet-name>
    <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CatalinaInvoker</servlet-name>
    <url-pattern>/catalina/*</url-pattern>
  </servlet-mapping>
</web-app>


테스트 웹 애플리케이션을 첨부합니다.
Refer to attached eclipse project file.
Eclipse 3.5 Project :

크리에이티브 커먼즈 라이센스
Creative Commons License
2011/03/09 10:30 2011/03/09 10:30

JBoss 5.0의 경우 설정 방식이나 디렉토리 구조가 조금 바뀌었습니다.

기존 방식에서는 $SERVER_HOME/deploy/jboss-web.deployer 파일을 이용하여 포트를 변경하였으나, 5.0에서 포트를 변경하기 위해서는 변경된 $SERVER_HOME/deploy/jbossweb.sar 디렉토리 하위의 server.xml파일을 변경하시면 됩니다.

<!-- A HTTP/1.1 Connector on port 8080 -->
      <Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}"
               connectionTimeout="20000" redirectPort="8443" />

      <!-- Add this option to the connector to avoid problems with
          .NET clients that don't implement HTTP/1.1 correctly
         restrictedUserAgents="^.*MS Web Services Client Protocol 1.1.4322.*$"
      -->

      <!-- A AJP 1.3 Connector on port 8009 -->
      <Connector protocol="AJP/1.3" port="8009" address="${jboss.bind.address}"
         redirectPort="8443" />


필요에 따라 AJP Connector도 변경하시면 됩니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2009/03/27 10:24 2009/03/27 10:24

JBoss를 사용하다 한글 처리에 대한 질문을 많이 받고 있습니다. 다국어 지원까지 포함해야 하는 경우도 종종 있습니다.

JBoss에서 한글 처리를 하기 위해서는 2가지의 작업이 필요합니다.

1. Web Application에 filter를 등록하기

첨부하는 파일을 이용하여 web.xml에 Encoding Filter를 등록하도록 합니다.
다음의 내용을 web.xml에 추가합니다.
<filter>
   <filter-name>Set Character Encoding</filter-name>
   <filter-class>filters.SetCharacterEncodingFilter</filter-class>
   <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>Set Character Encoding</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
JBoss level에서 엄격하게 스펙을 적용하는 통에.. 위의 url-pattern은 * 이 아니고 /* 이어야 합니다.

2. JBoss의 $SERVER_HOME/deploy/jboss-web.deployer/server.xml 파일을 열어 필요한 Connector 부분에 다음의 attribute를 추가합니다. JBoss의 default encoding은 ISO-8859-1입니다.
<Connector ... URIEncoding="UTF-8"/>

위와 같이 설정하면 다국어 지원까지 가능한 애플리케이션을 만들 수 있습니다.



크리에이티브 커먼즈 라이센스
Creative Commons License
2008/12/11 15:08 2008/12/11 15:08