[SPRING] Spring을 사용하는 CXF에서 다중 resouceBean 구성
SPRINGSpring을 사용하는 CXF에서 다중 resouceBean 구성
CXF RS 2.5.1을 Spring 3.0.6-RELEASE와 함께 사용하고 있습니다. "단일 종점"을위한 여러 구현 클래스를 갖고 싶습니다. 이 문제가보고되고 https://issues.apache.org/jira/browse/CXF-2439가 고정되어있는 것을 볼 수 있습니다. 그러나 CXF는 jaxrs : serviceBeans 태그에서 첫 번째 리소스 클래스를 선택합니다. 다른 요청의 경우, "요청 경로 / account / rest / transfer가 일치하는 작업이 없습니다"라는 메시지가 tomcat 콘솔에 표시됩니다. 아래는 구성입니다. 모든 입력을 감사하십시오.
을 포함한다.
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:account-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>CXF Servlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXF Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
account-servlet.xml
<jaxrs:server id="accountService" address="/rest">
<jaxrs:serviceBeans>
<ref bean="transferService" />
<ref bean="balanceService"/>
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
</jaxrs:server>
<bean id="transferService" class="com.mycompany.service.TransferService"/>
<bean id="balanceService" class="com.mycompany.service.BalanceService"/>
BalanceService.java (가져 오기 생략)
package com.mycompany.service;
@Path("/")
@Produces("application/xml")
public class BalanceService{
@GET
@Path("/balance")
public String getBalance() {
StringBuilder response = new StringBuilder(128);
response.append("<Balance>")
.append("<amount>").append("250.00").append("</amount>")
.append("</Balance>");
return response.toString();
}
}
TransferService.java (가져 오기 생략)
package com.mycompany.service;
@Path("/")
@Produces("application/xml")
public class TransferService {
@GET
@Path("/transfer")
public String getTransfer() {
StringBuilder response = new StringBuilder(128);
response.append("<Transfer>")
.append("<amount>").append("350.00").append("</amount>")
.append("</Transfer>");
return response.toString();
}
}
POC에 대한 샘플 응용 프로그램이므로 프로그래밍 불규칙성 / 표준을 무시하십시오.
해결법
-
==============================
1.@Path 매핑의 일부를 서비스 빈 클래스로 이동하여이 문제를 해결했습니다. 귀하의 경우 :
@Path 매핑의 일부를 서비스 빈 클래스로 이동하여이 문제를 해결했습니다. 귀하의 경우 :
BalanceService
@Path("/balance") @Produces("application/xml") public class BalanceService { @GET @Path("/{id}") public String getBalance(@PathParam("id") long id) { ... } }
전송 서비스
@Path("/transfer") @Produces("application/xml") public class TransferService { @GET @Path("/{id}") public String getTransfer(@PathParam("id") long id) { ... } }
-
==============================
2.그래서 나는 인터넷 검색에 약간의 시간을 할애하지만이 문제에 대한 해결책을 찾지 못했습니다. 문서를 작성하여 솔루션을 추론 할 수있는 메모가 있습니다.
그래서 나는 인터넷 검색에 약간의 시간을 할애하지만이 문제에 대한 해결책을 찾지 못했습니다. 문서를 작성하여 솔루션을 추론 할 수있는 메모가 있습니다.
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Customselectionbetweenmultipleresources
따라서 사용자 정의 리소스 비교기를 작성하고 적절한 jaxrs : server 구성 및 Eureka를 수행했습니다. 그것은 일했다!. 이제 javax : rs address의 단일 리소스 / 주소에 매핑 된 2 개의 구현 클래스가 있습니다.
아래 표시된 사용자 지정 리소스 비교기의 논리는 URL 패턴에 따라 달라질 수 있습니다.
모든 파일의 출처를 제공합니다. 이것이 미래에 누군가를 도울 수 있기를 바랍니다 :)
<web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/account-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CXF Servlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXF Servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
<beans> <jaxrs:server id="accountService" address="/rest"> <jaxrs:serviceBeans> <ref bean="accountServiceImpl" /> <ref bean="transferServiceImpl" /> </jaxrs:serviceBeans> <jaxrs:resourceComparator> <bean id="accountServiceComparator" class="com.etrade.comparator.AccountServiceComparator"/> </jaxrs:resourceComparator> <jaxrs:extensionMappings> <entry key="xml" value="application/xml" /> </jaxrs:extensionMappings> </jaxrs:server> <bean id="accountServiceImpl" class="com.etrade.service.AccountService" /> <bean id="transferServiceImpl" class="com.etrade.service.TransferService" /> </beans>
<modelVersion>4.0.0</modelVersion> <groupId>cxf.rest</groupId> <artifactId>account</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>account Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-bundle-jaxrs</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.0.5.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <!-- This plugin is needed for the servlet example --> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>7.2.0.v20101020</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <executions> <execution><goals><goal>java</goal></goals></execution> </executions> </plugin> </plugins> <finalName>account</finalName> </build> </project>
package com.etrade.comparator; import java.lang.reflect.Method; import javax.ws.rs.Path; import org.apache.cxf.jaxrs.ext.ResourceComparator; import org.apache.cxf.jaxrs.impl.UriInfoImpl; import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.message.Message; public class AccountServiceComparator implements ResourceComparator{ public int compare(ClassResourceInfo arg0, ClassResourceInfo arg1, Message message) { UriInfoImpl uriInfo = new UriInfoImpl(message); String path = uriInfo.getPath(); String[] pathArray = path.split("/"); String resourceUrlName = pathArray[1]; System.out.println("Path : "+resourceUrlName); Method[] methods = arg0.getServiceClass().getMethods(); int value = 1; String resource = null; for(Method method : methods) { Path annotationPath = method.getAnnotation(javax.ws.rs.Path.class); if(null != annotationPath){ String pathValue = annotationPath.value(); String[] parts = pathValue.split("/"); resource = parts[1]; System.out.println("resource : "+resource); } if(resourceUrlName.contains(resource)){ value = -1; } } return value; } public int compare(OperationResourceInfo arg0, OperationResourceInfo arg1, Message arg2) { return 0; } }
package com.etrade.service; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/account") @Produces("application/xml") public class AccountService { @GET @Produces("application/xml") @Path("/balance/{id}") public String accountBalance(@PathParam("id") long id) { System.out.println("id : "+id); StringBuilder response = new StringBuilder(256); response.append("<Response>").append("<id>").append(id) .append("</id>").append("<balance>").append("250.00").append("</balance>") .append("</Response>"); return response.toString(); } }
package com.etrade.service; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/account") @Produces("application/xml") public class TransferService { @GET @Produces("application/xml") @Path("/transfer/{id}") public String accountTransfer(@PathParam("id") long id) { System.out.println("transfer id : "+id); StringBuilder response = new StringBuilder(256); response.append("<Response>").append("<id>").append(id) .append("</id>").append("<transfer>").append("250.00").append("</transfer>") .append("</Response>"); return response.toString(); } }
http://localhost:8080/rest/account/balance/12 http://localhost:8080/rest/transfer/balance/13
-
==============================
3.당신은 아마도 루트 리소스를 비교하는 것과 같은 로직을 단순화 할 수 있습니다. 예를 들어, 요청 URI와 루트 리소스 클래스의 이름을 알면 결정을 내리기에 충분할 수 있습니다. 개별 메소드를 검사하는 것이 복잡해 보입니다. BTW에서 사용자 지정 리소스 비교자는 루트 리소스 및 / 또는 개별 리소스 메서드가 동등한 후보가 될 수있는 경우에만 필요합니다.
당신은 아마도 루트 리소스를 비교하는 것과 같은 로직을 단순화 할 수 있습니다. 예를 들어, 요청 URI와 루트 리소스 클래스의 이름을 알면 결정을 내리기에 충분할 수 있습니다. 개별 메소드를 검사하는 것이 복잡해 보입니다. BTW에서 사용자 지정 리소스 비교자는 루트 리소스 및 / 또는 개별 리소스 메서드가 동등한 후보가 될 수있는 경우에만 필요합니다.
-
==============================
4.나는이 방법으로 문제를 해결할 것이다.
나는이 방법으로 문제를 해결할 것이다.
그리고 그게 전부입니다. :)
from https://stackoverflow.com/questions/9725770/multiple-resoucebean-configuration-in-cxf-using-spring by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링에서 JSON 응답을 래핑하는 방법은 무엇입니까? (0) | 2019.04.01 |
---|---|
[SPRING] Spring applicationContext.xml에서 데이터 소스로 P6Spy 사용 (0) | 2019.04.01 |
[SPRING] 그것은 나를 500 던졌습니다 봄 보안에 표현 'ROLE_USER'을 평가하지 못했습니다 (0) | 2019.04.01 |
[SPRING] 스프링 부트 JAX-WS 웹 서비스를 bean으로 등록 (0) | 2019.04.01 |
[SPRING] Spring - No WebApplicationContext found : ContextLoaderListener가 등록되지 않았습니까? [복제] (0) | 2019.04.01 |