Spring RssChannelHttpMessageConverter - spring

Does anyone have an example of using the Spring RssChannelHttpMessageConverter to generate a rss podcast?
This is what I have so far.
#Controller
public class FeedController {
private Jaxb2Marshaller jaxb2Mashaller;
#Autowired
public void setJaxb2Mashaller(Jaxb2Marshaller jaxb2Mashaller) {
this.jaxb2Mashaller = jaxb2Mashaller;
}
#RequestMapping(method= RequestMethod.GET, value="/emps",
headers="Accept=application/rss+xml")
public #ResponseBody SyndFeed getFeed(){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Query query = session.createQuery("from Show");
List<Show> l = query.list();
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss2.0");
feed.setTitle("some podcast");
feed.setLink("you");
feed.setDescription("description");
feed.setCopyright("c_me");
List<SyndEntry> entries = new ArrayList<SyndEntry>();
for(Show e : l) {
SyndEntry entry = new SyndEntryImpl();
entry.setTitle(e.getTitle());
entries.add(entry);
}
feed.setEntries(entries);
System.out.println(feed);
return feed;
}
}
When calling the controller I get a 406 Not Acceptable
Here is some snippets of my spring config
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="marshallingConverter" />
<ref bean="atomConverter" />
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean id="atomConverter" class="org.springframework.http.converter.feed.RssChannelHttpMessageConverter">
<property name="supportedMediaTypes" value="application/rss+xml" />
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<!-- Client -->
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="marshallingConverter" />
<ref bean="atomConverter" />
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jaxbMarshaller"
class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.Show</value>
</list>
</property>
</bean>

Related

Call SOAP service asynchronously using Spring

I've to call a SOAP web service asynchronously. Currently, I'm calling it in a synchronous way using Spring webservicetemplate.
Current config is like:
<bean id="interceptedHttpClientBuilder" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="httpClientBuilder" />
<property name="targetMethod" value="addInterceptorFirst"> </property>
<property name="arguments">
<list>
<bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender.RemoveSoapHeadersInterceptor"/>
</list>
</property>
</bean>
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig" factory-method="custom">
<property name="socketTimeout" value="120000" />
</bean>
<bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build" />
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
<property name="defaultRequestConfig" ref="requestConfig" />
</bean>
<bean id="messageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
<constructor-arg ref="httpClient"></constructor-arg>
</bean>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan">
<list><value>...</value></list>
</property>
</bean>
<bean id="wsClientSecurityInterceptor"
class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="UsernameToken" />
<property name="securementUsername"><value>${username}</value></property>
<property name="securementPassword"><value>${password}</value></property>
<property name="securementPasswordType" value="PasswordText" />
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="marshaller" ref="jaxb2Marshaller"></property>
<property name="unmarshaller" ref="jaxb2Marshaller"></property>
<property name="defaultUri"><value>${ws.url}</value></property>
<property name="interceptors">
<list>
<ref local="wsClientSecurityInterceptor"/>
</list>
</property>
<property name="messageSender" ref="messageSender"></property>
</bean>
Java call looks like:
MyResponse response = (MyResponse) webServiceTemplate.marshalSendAndReceive(req, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
((SoapMessage) message).setSoapAction("test");
}
});
May I know how can I change it to call the service asynchronously? Or Do I need to use something else in spring to achieve this?
Not sure why you use spring-integration tag in your question, but if we are here, please, definitely take a look into the #MessagingGateway with the Future<> as a return type: https://docs.spring.io/spring-integration/docs/5.0.1.RELEASE/reference/html/messaging-endpoints-chapter.html#async-gateway
The SOAP WebService can be called via Spring Integration <int-ws:outbound-gateway>: https://docs.spring.io/spring-integration/docs/5.0.1.RELEASE/reference/html/ws.html
The samples are here: https://github.com/spring-projects/spring-integration-samples
To be more clear the code might looks like this:
<int:gateway id="mathService"
service-interface="org.springframework.integration.samples.async.gateway.MathServiceGateway"
default-request-channel="requestChannel"
async-executor="executor"/>
Where that MathServiceGateway is like this:
public interface MathServiceGateway {
Future<Integer> multiplyByTwo(int i);
}
The WS call is simple as well:
<int-ws:outbound-gateway request-channel="requestChannel" uri="http://www.w3schools.com/xml/tempconvert.asmx"/>

How can I invoke multiple web services using JAXB in Spring?

I'm building an application with Spring MVC (3.2). This application need to invoke to 2 web services. It's ok when I invoke each service separately. However, it's not work when I call both. My application config file:
<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
</property>
</bean>
<!-- The first service-->
<bean id="local" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"
p:contextPath="com.ws" />
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="marshaller" ref="local" />
<property name="unmarshaller" ref="local" />
<property name="defaultUri"
value="http://localhost:9999/ws/ProcessService" />
</bean>
<!-- The second service-->
<bean id="preconvert" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"
p:contextPath="com.ws.preprocess" />
<bean id="wstemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory" />
<property name="marshaller" ref="preconvert" />
<property name="unmarshaller" ref="preconvert" />
<property name="defaultUri"
value="http://localhost:9999/jod/PreProcessService" />
</bean>
Help me please! Thanks.
Hi chicky I solved the problem
Beans XML
<bean id="webServiceTemplate1" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/>
<property name="marshaller" ref="marshaller1"/>
<property name="unmarshaller" ref="marshaller1"/>
<property name="defaultUri" value="http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"/>
</bean>
<bean id="webServiceTemplate2" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/>
<property name="marshaller" ref="marshaller2"/>
<property name="unmarshaller" ref="marshaller2"/>
<property name="defaultUri" value="http://www.w3schools.com/webservices/tempconvert.asmx?WSDL"/>
</bean>
webServiceTemplate1 service
#Autowired
private WebServiceTemplate webServiceTemplate1;
#Override
public double obtenerCambio(String from, String to) {
ConversionRate conversionRate = new ObjectFactory().createConversionRate();
conversionRate.setFromCurrency(Currency.fromValue(from));
conversionRate.setToCurrency(Currency.fromValue(to));
ConversionRateResponse conversionRateResponse = (ConversionRateResponse) webServiceTemplate1.marshalSendAndReceive(conversionRate);
return conversionRateResponse.getConversionRateResult();
}
And webServiceTemplate2
#Autowired
private WebServiceTemplate webServiceTemplate2;
#Override
public String obtenerConversion(String celcius) {
CelsiusToFahrenheit celsiusToFahrenheit = new ObjectFactory().createCelsiusToFahrenheit();
celsiusToFahrenheit.setCelsius(celcius);
CelsiusToFahrenheitResponse response = (CelsiusToFahrenheitResponse) webServiceTemplate2.marshalSendAndReceive(celsiusToFahrenheit);
return response.getCelsiusToFahrenheitResult();
}

SPring 3.2 Path variable truncating

I know this has been asked before. However In spite of doing everything as suggested I am facing an issue.
if my path variable has .jpg extension, it is getting truncated.
Here are my settings
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean
class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>image/jpeg</value>
<value>image/jpg</value>
<value>image/png</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<util:list>
<ref bean="jsonMessageConverter" />
</util:list>
</property>
</bean>
<bean name="exceptionHandlerExceptionResolver"
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
<property name="order" value="0" />
<property name="contentNegotiationManager" ref="contentNegotiationManager" />
</bean>
<bean name="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="contentNegotiationManager" ref="contentNegotiationManager" />
<property name="useSuffixPatternMatch" value="false" />
<property name="useTrailingSlashMatch" value="true"></property>
</bean>
Controller
#RequestMapping(value = "image/{fileName}", method = RequestMethod.GET, produces = { MediaType.IMAGE_JPEG_VALUE,
MediaType.IMAGE_GIF_VALUE, MediaType.IMAGE_PNG_VALUE })
public #ResponseBody
byte[] getImage(#PathVariable("fileName") final String fileName);
Do I need to do more?
Try this (note the updated value for #RequestMapping)
#RequestMapping(value = "image/{fileName:[a-z]\\.[a-z]}}", method = RequestMethod.GET, produces = { MediaType.IMAGE_JPEG_VALUE,
MediaType.IMAGE_GIF_VALUE, MediaType.IMAGE_PNG_VALUE })
public #ResponseBody
byte[] getImage(#PathVariable("fileName") final String fileName);
See reference here.

Spring HTTP.DELETE return code 415 unsupported mediatype

#ResponseBody
#RequestMapping(method = RequestMethod.DELETE)
public String deleteState(#RequestBody String message) {
System.out.println("controller");
int resp = stateService.delete(message);
return resp == 1 ? "State deleted successfully : HTTP 200"
: "delete operation failed : HTTP 400";
}
when I post a json { stateName: VA}, it returns 415 error, Can any one suggest something please?
#Override
#Transactional
public int delete(Object message) {
System.out.println("service");
JSONObject jsonObj = null;
try {
jsonObj = new JSONObject((String) message);
Parameters p = new Parameters();
p.property = "state_name";
p.value = (String) jsonObj.getString("stateName");
System.out.println("service");
return stateDAO.delete(p);
} catch (Exception e) {
return 0;
}
}
This is what I am doing in the service...
Update : Here is my Spring Configuration:
<context:annotation-config />
<!-- Scans the classpath of this application for #Components to deploy as
beans -->
<context:component-scan base-package="com.tutorial.jquery" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/spring/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="org.postgresql.Driver"
p:url="jdbc:postgresql://localhost:5432/processdb" p:username="postgres"
p:password="postgres" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- >bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"
/> <property name="order" value="0" /> <property name="prefix"> <value>/WEB-INF/views/</value>
</property> <property name="suffix"> <value>.html</value> </property> </bean -->
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="2" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
</bean>
</list>
</property>
</bean>
<!-- If no extension matched, use JSP view -->
<bean id="htmlView"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="1" />
<property name="prefix">
<value>/views/</value>
</property>
<property name="suffix">
<value>.html</value>
</property>
</bean>
I updated the method to get it working:
#ResponseBody
#RequestMapping(method = RequestMethod.DELETE)
public String deleteState(HttpServletRequest request,
HttpServletResponse response) {
Map<String, String[]> parameters = request.getParameterMap();
//System.out.print("RequestParam: " + state_Name);
int resp = stateService.delete(parameters.get("state_name")[0]);
return resp == 1 ? "State deleted successfully : HTTP 200"
: "delete operation failed : HTTP 400";
}
This fixed the issue
Thanks!
Try this,
change
#RequestBody String message
to
#RequestParam String stateName

Spring: How to inject a property with a non-setter method?

Is it possible to inject a property bean through a method with a signature doesn't start with set?
Specifically, I'm trying to use Spring to configure an embedded Jetty instance and I need to be able to inject a servlet bean via an addServlet() method.
I am looking at Jetty/Tutorial/Embedding Jetty documentation. I guess you mean calling ServletContextHandler.addServlet(). You have few choices:
#Configuration (since 3.0)
My favourite approach. You can configure everything using Java!
#Configuration
public class Jetty {
#Bean(initMethod = "start")
public Server server() {
Server server = new Server(8080);
server.setHandler(context());
return server;
}
#Bean
public ServletContextHandler context() {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(servlet(), "/*");
return context;
}
#Bean
public ServletHolder servletHolder() {
return new ServletHolder(helloServlet());
}
#Bean
public HelloServlet helloServlet() {
return new HelloServlet();
}
}
Inheritance/decorating
You can inherit from or wrap original ServletContextHandler class to follow Java bean naming conventions. Of course it requires an extra class, but makes Jetty class Spring-friendly. You can even publish such wrapper or maybe someone already did that?
MethodInvokingFactoryBean
I don't like this approach as it seems too low level. Basically you create a bean that calls arbitrary method with arbitrary arguments:
<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="servletContextHandler"/>
<property name="targetMethod" value="addServlet"/>
<property name="arguments">
<list>
<ref bean="yourServlet"/>
</list>
</property>
</bean>
just the spring file adapted to Jetty 7. It's possible to add yours contextHandlers...
<bean id="contexts"
class="org.eclipse.jetty.server.handler.ContextHandlerCollection" />
<context:property-placeholder location="src/main/resources/ws.properties" />
<!-- Manually start server after setting parent context. (init-method="start") -->
<bean id="jettyServer" class="org.eclipse.jetty.server.Server"
destroy-method="stop">
<property name="threadPool">
<bean id="ThreadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<property name="minThreads" value="10" />
<property name="maxThreads" value="50" />
</bean>
</property>
<property name="connectors">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<property name="port" value="8181" />
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="contexts" />
<bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" />
<bean class="org.eclipse.jetty.servlet.ServletContextHandler"
p:contextPath="/${ws.context.path}">
<property name="sessionHandler">
<bean class="org.eclipse.jetty.server.session.SessionHandler" />
</property>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder"
p:name="spring-ws">
<property name="servlet">
<bean
class="org.springframework.ws.transport.http.MessageDispatcherServlet" />
</property>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:/spring-ws-context.xml" />
</map>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping"
p:servletName="spring-ws" p:pathSpec="/*" />
</list>
</property>
</bean>
</property>
</bean>
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler" />
</list>
</property>
</bean>
</property>
</bean>

Resources