301.7. 샘플
Camel 2.7 이후부터 Spring 웹 애플리케이션에서 Servlet 을 더 쉽게 사용할 수 있습니다. 자세한 내용은 Servlet Tomcat 예제 를 참조하십시오.
이 샘플에서는 http://localhost:8080/camel/services/hello 에서 HTTP 서비스를 노출하는 경로를 정의합니다.
먼저 일반 웹 컨테이너 또는 OSGi 서비스를 통해 CamelHttpTransportServlet 을 게시해야 합니다. Web.xml
파일을 사용하여 다음과 같이 CamelHttpTransportServlet 을 게시합니다.
<web-app> <servlet> <servlet-name>CamelServlet</servlet-name> <display-name>Camel Http Transport Servlet</display-name> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CamelServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app>
그러면 다음과 같이 경로를 정의할 수 있습니다.
from("servlet:hello?matchOnUriPrefix=true").process(new Processor() { public void process(Exchange exchange) throws Exception { String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class); String path = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class); path = path.substring(path.lastIndexOf("/")); assertEquals("Get a wrong content type", CONTENT_TYPE, contentType); // assert camel http header String charsetEncoding = exchange.getIn().getHeader(Exchange.HTTP_CHARACTER_ENCODING, String.class); assertEquals("Get a wrong charset name from the message heaer", "UTF-8", charsetEncoding); // assert exchange charset assertEquals("Get a wrong charset naem from the exchange property", "UTF-8", exchange.getProperty(Exchange.CHARSET_NAME)); exchange.getOut().setHeader(Exchange.CONTENT_TYPE, contentType + "; charset=UTF-8"); exchange.getOut().setHeader("PATH", path); exchange.getOut().setBody("<b>Hello World</b>"); } });
camel-servlet 끝점의 상대 경로 지정
게시된 서블릿으로 HTTP 전송을 바인딩하고 있으며 서블릿의 애플리케이션 컨텍스트 경로를 알 수 없으므로 camel-servlet
끝점은 상대 경로를 사용하여 끝점의 URL을 지정합니다. 클라이언트는 서블릿 게시 주소를 통해 camel-servlet
끝점에 액세스할 수 있습니다. ("http://localhost:8080/camel/services") + RELATIVE_PATH("/hello")
301.7.1. Spring 3.x 사용 시 샘플
Servlet Tomcat 예제 를 참조하십시오.
301.7.2. Spring 2.x 사용 시 샘플
Camel/Spring 애플리케이션에서 Servlet 구성 요소를 사용할 때 Servlet 구성 요소가 시작된 후 Spring ApplicationContext를 로드해야 하는 경우가 많습니다. 이 작업은 ContextLoaderListener
대신 Spring의 ContextLoaderServlet
을 사용하여 수행할 수 있습니다. 이 경우 다음과 같이 CamelHttpTransportServlet 을 시작한 후 ContextLoaderServlet
을 시작해야 합니다.
<web-app> <servlet> <servlet-name>CamelServlet</servlet-name> <servlet-class> org.apache.camel.component.servlet.CamelHttpTransportServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>SpringApplicationContext</servlet-name> <servlet-class> org.springframework.web.context.ContextLoaderServlet </servlet-class> <load-on-startup>2</load-on-startup> </servlet> <web-app>
301.7.3. OSGi 사용 시 샘플
Camel 2.6.0 에서는 다음과 같이 블루프린트를 사용하여 CamelHttpTransportServlet 을 OSGi 서비스로 게시할 수 있습니다.
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet" /> <!-- Enlist it in OSGi service registry. This will cause two things: 1) As the pax web whiteboard extender is running the CamelServlet will be registered with the OSGi HTTP Service 2) It will trigger the HttpRegistry in other bundles so the servlet is made known there too --> <service ref="camelServlet"> <interfaces> <value>javax.servlet.Servlet</value> <value>org.apache.camel.http.common.CamelServlet</value> </interfaces> <service-properties> <entry key="alias" value="/camel/services" /> <entry key="matchOnUriPrefix" value="true" /> <entry key="servlet-name" value="CamelServlet" /> </service-properties> </service> </blueprint>
그런 다음 다음과 같이 Camel 경로에서 이 서비스를 사용합니다.
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <reference id="servletref" ext:proxy-method="classes" interface="org.apache.camel.http.common.CamelServlet"> <reference-listener ref="httpRegistry" bind-method="register" unbind-method="unregister" /> </reference> <bean id="httpRegistry" class="org.apache.camel.component.servlet.DefaultHttpRegistry" /> <bean id="servlet" class="org.apache.camel.component.servlet.ServletComponent"> <property name="httpRegistry" ref="httpRegistry" /> </bean> <bean id="servletProcessor" class="org.apache.camel.example.servlet.ServletProcessor" /> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <!-- Notice how we can use the servlet scheme which is that reference above --> <from uri="servlet://hello" /> <process ref="servletProcessor" /> </route> </camelContext> </blueprint>
Camel 2.6 이전 버전의 경우 Activator
를 사용하여 CamelHttpTransportServlet 을 OSGi 플랫폼에 게시할 수 있습니다.
import java.util.Dictionary; import java.util.Hashtable; import org.apache.camel.component.servlet.CamelHttpTransportServlet; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpContext; import org.osgi.service.http.HttpService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.osgi.context.BundleContextAware; public final class ServletActivator implements BundleActivator, BundleContextAware { private static final Logger LOG = LoggerFactory.getLogger(ServletActivator.class); private static boolean registerService; /** * HttpService reference. */ private ServiceReference<?> httpServiceRef; /** * Called when the OSGi framework starts our bundle */ public void start(BundleContext bc) throws Exception { registerServlet(bc); } /** * Called when the OSGi framework stops our bundle */ public void stop(BundleContext bc) throws Exception { if (httpServiceRef != null) { bc.ungetService(httpServiceRef); httpServiceRef = null; } } protected void registerServlet(BundleContext bundleContext) throws Exception { httpServiceRef = bundleContext.getServiceReference(HttpService.class.getName()); if (httpServiceRef != null && !registerService) { LOG.info("Register the servlet service"); final HttpService httpService = (HttpService)bundleContext.getService(httpServiceRef); if (httpService != null) { // create a default context to share between registrations final HttpContext httpContext = httpService.createDefaultHttpContext(); // register the hello world servlet final Dictionary<String, String> initParams = new Hashtable<String, String>(); initParams.put("matchOnUriPrefix", "false"); initParams.put("servlet-name", "CamelServlet"); httpService.registerServlet("/camel/services", // alias new CamelHttpTransportServlet(), // register servlet initParams, // init params httpContext // http context ); registerService = true; } } } public void setBundleContext(BundleContext bc) { try { registerServlet(bc); } catch (Exception e) { LOG.error("Cannot register the servlet, the reason is " + e); } } }
301.7.4. Spring-Boot 사용
Camel 2.19.0 이후의 camel-servlet-starter 라이브러리는 /camel/*
컨텍스트 경로 아래의 나머지 모든 끝점을 자동으로 바인딩합니다. 다음 표에는 camel-servlet-starter 라이브러리에서 사용할 수 있는 추가 구성 속성이 요약되어 있습니다. Camel 서블릿의 자동 매핑을 비활성화할 수도 있습니다.
Spring-Boot 속성 | 기본 | 설명 |
---|---|---|
camel.component.servlet.mapping.enabled |
| 스프링 웹 컨텍스트로 서블릿 구성 요소의 자동 매핑 활성화 |
camel.component.servlet.mapping.context-path |
| 자동 매핑을 위해 서블릿 구성 요소에서 사용하는 컨텍스트 경로 |
camel.component.servlet.mapping.servlet-name |
| Camel 서블릿의 이름 |