i have problem with build my own webservice based on cxf/camel.
My webservice should do something like this:
I am on DomainA from which i send POST data to my webservice (CXF)
my CXF code is:
#Path("/")
#ProduceMime({ "application/json" })
public class SSO {
#POST
#Path("/user")
#ProduceMime({ "application/json" })
public String user(#FormParam("id") String token) {
}
}
My CXF code receive my id variable.
Now i want to send this variable to other url http://localhost:8080/myWebSite and wait for response from the url and after get the response send it to DomainA
my beans.xml is:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/osgi/cxf-extension-osgi.xml" />
<bean id="cxfSSO" class="com.esb.cxf.SSO" />
<jaxrs:server id="sso" address="/sso">
<jaxrs:serviceBeans>
<ref bean="cxfSSO" />
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
The easiest way is going to be a Spring RestTemplate, as this hides a huge amount of the complexity that you'd otherwise have to deal with.
The Spring documentation describes the basics, but be aware that you'll want to build the request as a MultiValueMap<String, String> so that it will be sent to the service as application/x-www-form-urlencoded.
Related
I'm using Camel REST with Camel servlet handling the REST transport and want to change the way headers from the exchange are processed in HTTP requests and responses. I'm using Spring XML to configure my application. Here's the relevant configuration I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
<bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
<bean id="servlet" class="org.apache.camel.component.servlet.ServletComponent">
<property name="httpBinding" ref="myHttpBinding"/>
</bean>
<!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
<camel:camelContext id="myCamelContext">
<camel:contextScan/>
<camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
<camel:corsHeaders key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
<camel:corsHeaders key="Access-Control-Allow-Origin" value="*"/>
<camel:corsHeaders key="Access-Control-Allow-Headers" value="*"/>
</camel:restConfiguration>
</camel:camelContext>
</beans>
When the routes are created, I see that the endpoints are configured with MyHttpBinding set. However, incoming requests are still using ServletRestHttpBinding. This is because when Camel creates the consumer, it executes this block of code:
if (!map.containsKey("httpBinding")) {
// use the rest binding, if not using a custom http binding
HttpBinding binding = new ServletRestHttpBinding();
binding.setHeaderFilterStrategy(endpoint.getHeaderFilterStrategy());
binding.setTransferException(endpoint.isTransferException());
binding.setEagerCheckContentAvailable(endpoint.isEagerCheckContentAvailable());
endpoint.setHttpBinding(binding);
}
How can I set the HTTP binding in a way that Camel will respect it?
Because Camel ultimately looks for the httpBinding property on the endpoint to determine the binding strategy to use, the REST component has to be configured to add that property to the endpoint like so:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- Custom Camel Configuration //////////////////////////////////////////////////////////////////////////////// -->
<bean id="myHttpBinding" class="com.example.MyHttpBinding"/>
<!-- Routes //////////////////////////////////////////////////////////////////////////////////////////////////// -->
<camel:camelContext id="myCamelContext">
<camel:contextScan/>
<camel:restConfiguration component="servlet" enableCORS="true" bindingMode="json" skipBindingOnErrorCode="false">
<camel:endpointProperty key="httpBinding" value="myHttpBinding"/>
<camel:corsHeaders key="Access-Control-Allow-Methods" value="PATCH, PUT, POST, DELETE, GET, OPTIONS, HEAD"/>
<camel:corsHeaders key="Access-Control-Allow-Origin" value="*"/>
<camel:corsHeaders key="Access-Control-Allow-Headers" value="*"/>
</camel:restConfiguration>
</camel:camelContext>
</beans>
Note that I removed the custom servlet component because it wasn't necessary.
I have a basic spring MVC project (the basic mold they create) and am trying to get it to run a html instead of a JSP (JSP works perfect)
my controller
#Controller
#RequestMapping("/")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Hello world!");
return "index";
}
}
my mvc dispatcher service
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.springapp.mvc"/>
<!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
<!--<property name="prefix" value="/WEB-INF/pages/"/>-->
<!--<property name="suffix" value=""/>-->
<!--</bean>-->
<mvc:resources mapping="/WEB-INF/pages/" location="/WEB-INF/pages/" />
I've tried numerous things, such as mapping to /WEB-INF/pages/** , removing the InternalResourceViewResolver completely (W/ the previous mappings,) leaving the suffix empty, with html, etc but to no avail. I've looked at the other questions similar to this but no luck. Also read about static folder for the htmls, but was confused... What am I doing wrong?
the file structure for webpages
webapp
--WEB-INF
----pages
------hello.jsp, index.html
<mvc:resources mapping="/WEB-INF/pages/" location="/WEB-INF/pages/" />
Mapping value stands for URL mapping. So give here for example "/pages/**"
<mvc:resources mapping="/pages/**" location="/WEB-INF/pages/" />
Now you can access to static files like html page by localhost:8080/app/pages/index.html for example.
In Java Controller instead of return "index"; there should be return "redirect:/pages/index.html";
Read this example to get all detailed informations. Hope i could help.
I've created a simple Spring-based web application, with a #RestController annotation for a class that one of its mappings returns a JSON response.
It works perfectly when I run it on localhost, but I get the following error when I try to call the url on the host it is deployed to (Bluemix). I got this exception on the localhost version, when I didn't define the class as #RestController (or it's parallel - #Controller & #ResponseBody):
'Exception thrown by application class 'org.springframework.web.servlet.view.InternalResourceView.prepareForRendering:205'
javax.servlet.ServletException: Circular view path [nextStep]: would dispatch back to the current handler URL [/nextStep] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)'
These are my definitions:
RestController
#Controller
#ResponseBody
public class InterviewRESTController {
#Autowired
private transient InterviewFlowLogic interviewFlowLogic;
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping("/nextStep")
public ServiceRESTResponse nextStep(#RequestParam(value="name", defaultValue="World") String name){
return new ServiceRESTResponse(counter.incrementAndGet(),
String.format(template, name));
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="il.intervyo.client.controller"></context:component-scan>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
</bean>
</beans>
Again, it is important to stress out that this code works when I run it localhost and the url returns the Json format response, but fails only on the deployed version - I saw the few questions-and-answers that are already on the site, non of them refers to this specific issue.
I'd gladly supply with any additional info needed (pom.xml, web.xml, etc.)
I'm trying to handle error in CXF rest service. Which i want to gain is a situation when user is trying to send request and he's choosing a wrong path. I would like to handle this situation. The default responses are:
2014-05-15 14:07:14 INFO [qtp811959489-40] LoggingOutInterceptor:234 - Outbound Message
---------------------------
ID: 1
Response-Code: 405
Content-Type:
Headers: {Allow=[POST, GET, OPTIONS, HEAD], Date=[Thu, 15 May 2014 12:07:14 GMT], Content-Length=[0]}
My resource class:
#Path("payment/v1/")
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class OneApiResource {
#GET
#Path("/{endUserId}/transactions")
public PaymentTransactionListWrapper listTransactions(#PathParam("endUserId") String endUserId) {
return null;
}
}
endpoint:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
">
<bean id="jsonProviderFactory" class="model.oneApi.JsonProviderFactory"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<cxf:rsServer id="bieService"
address="http://{{endpoint.jetty.app.oneApi.host}}:{{endpoint.jetty.app.oneApi.service.port}}/{{endpoint.jetty.app.oneApi.service.ctx}}/"
loggingFeatureEnabled="true"
serviceClass="model.oneApi.OneApiResource"
loggingSizeLimit="-1"
skipFaultLogging="false">
<cxf:providers>
<bean factory-bean="jsonProviderFactory" factory-method="create"/>
</cxf:providers>
<cxf:inFaultInterceptors>
<ref bean="logOutbound"/>
</cxf:inFaultInterceptors>
<cxf:outFaultInterceptors>
<ref bean="logOutbound"/>
</cxf:outFaultInterceptors>
</cxf:rsServer>
</beans>
Is there any way to handle it?
I 'm using Spring 3.0.1.RELEASE for my webapp (and i have no way for upgrading it) and i'm trying to render some images from database on web-page.
I have following simple Spring configs:
spring-application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<task:annotation-driven />
<context:annotation-config />
<context:spring-configured />
<context:component-scan base-package="com.me" />
<bean id="hibernateSessionFactory" class="com.me.dbaccess.HibernateSessionFactory">
<constructor-arg ref="sessionFactory"/>
</bean>
</beans>
spring-mvc.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<bean id="tilesViewResolver" class="com.me.util.TilesExposingBeansViewResolver">
<property name="viewClass" value="com.me.util.TilesExposingBeansView"/>
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/config/tiles-defs.xml</value>
</list>
</property>
</bean>
</beans>
I have following controller:
#Controller
public class PhotoController {
#RequestMapping("/carPhoto.html")
#ResponseBody
public byte[] getCarPhoto(
#RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
#RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
//return image's bytes array from db by photo Id and Type;
}
}
And finally, I have simple jsp-page:
<%#page contentType="text/html; charset=utf-8"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<img id="photoImage" src="<c:url value="/carPhoto.html?photoType=1&photoId=22556793"/>" />
If I open this page - I can see this image without any problems.
But if I copy image "src" attribute and paste it in browser's address bar (Firefox 19.0.2) - then browser offers me to save carPhoto.html, instead of just render the image.
Should I perform some additional setup?
The problem is, that you have to specify the mime type (and if your image is larger you will need to specify its length too).
An other solution () is to return a Spring ResponseEntity or HttpEntity (HttpEntity is enough if you always return http status code 200, ResponseEntity (a subclass of HttpEntity) is for example needed if you want to return other http status codes, like not found).
#Controller
public class PhotoController {
#RequestMapping("/carPhoto.html")
#ResponseBody
public HttpEntity<byte[]> getCarPhoto(
#RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
#RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
byte[] image = image's bytes array from db by photo Id and Type;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG); //or what ever type it is
headers.setContentLength(image.length);
return new HttpEntity<byte[]>(image, headers);
}
}
There are several ways. Easiest is to use #ResponseBody with a byte[] as your return type, set your Content-Type and such, the write the bytes to the output stream using the HttpServletResponse.
A more elegant solution (IMO) would be to return a ModelAndView, then set the View on that to a custom view that sets the proper headers (Content-Type and such) and writes out the bytes to the HttpServletResponse's output stream.