how can I get the response message from Axis2 in spring integration - spring

I need to integrate my webservice (Axis2) in spring integration: I have spring-axis2-message.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:ws="http://www.springframework.org/schema/integration/ws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/ws
http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd">
<chain input-channel="messageChannelIN" output-channel="messageChannelOUT">
<ws:header-enricher >
<ws:soap-action value="getMessageService"/>
</ws:header-enricher>
<ws:outbound-gateway uri="http://localhost:8080/axis2-webservice/services/wservices?wsdl" reply-channel="messageChannelOUT"/>
</chain>
<!-- The response from the service is logged to the console. -->
<stream:stdout-channel-adapter id="messageChannelOUT" append-newline="true" />
</beans:beans>
And a TestAxis2.java
package org.neos.spring.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.core.DestinationResolver;
public class TestAxis2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/spring-axis2-message.xml");
DestinationResolver<MessageChannel> channelResolver = new BeanFactoryChannelResolver(context);
String requestXml =
"<getMessageService xmlns=\"http://service.ws.axis2.neos.org\">" +
"<name>HUGO</name>"
+ "</getMessageService>";
// Create the Message object
Message<String> message = MessageBuilder.withPayload(requestXml).build();
// Send the Message to the handler's input channel
MessageChannel channel = channelResolver.resolveDestination("messageChannelIN");
channel.send(message);
}
}
The program run very well and I can see in the console the next response:
<?xml version="1.0" encoding="UTF-8"?><ns:getMessageServiceResponse xmlns:ns="http://service.ws.axis2.neos.org"><ns:return>HELLO HUGO!, WELCOME TO WEBSERVICE AXIS1 hola</ns:return></ns:getMessageServiceResponse>
My question is how Can I manipulate/How can get the response in Java program because I need the response. I tried to do a lot of things but unfortunately did not work anything I only can see the response in the console but I need to manipulate the response.
I do not how can I access this configuration or if I need to configurate other things.
access<stream:stdout-channel-adapter id="messageChannelOUT" append-newline="true" />
Can Anyone help me please?

Use a Messaging Gateway.
public interface Gateway
String sendAndReceive(String out);
}
<int:gateway service-interface="foo.Gateway"
default-request-channel="messageChannelIN" />
Remove the output-channel from the chain
The reply will be returned to the caller via the gateway
Gatweway gw = context.getBean(Gateway.class);
...
String reply = gw.sendAndReceive(requestXml);
This has the added bonus of not exposing your application to the messaging infrastructure.

It's working my program right now!!. Thanks for your help Gary Russell!!! your comments were very useful.
The final code was:
xml configuration
........
<chain input-channel="messageChannelIN">
<ws:header-enricher>
<ws:soap-action value="getMessageService"/>
</ws:header-enricher>
<ws:outbound-gateway uri="http://localhost:8080/axis2-webservice/services/wservices?wsdl" />
</chain>
<gateway id="messageChannelOUT" service-interface="org.neos.spring.ws.service.GatewayAxis" default-request-channel="messageChannelIN"/>
Java Code:
public interface GatewayAxis {
#Gateway
String sendAndReceive(String out);}
TestAxis2
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/spring-axis2-message.xml");
GatewayAxis gateway = context.getBean(GatewayAxis.class);
String requestXml =
"<getMessageService xmlns=\"http://service.ws.axis2.neos.org\">" +
"<name>HUGO</name>"
+ "</getMessageService>";
String reply = gateway.sendAndReceive(requestXml);
System.out.println(reply);
}

Related

SpringBoot and use / load a dynamic "applicationContext.xml" instead of hard coded one

I've seen a hundred examples of this:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
#SpringBootApplication
#ImportResource("classpath:applicationContext.xml")
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
And I have been on a rabbit trail for many hours now.
I am building a framework....and I need load (a handful of dependencies, not all of them...) from the xml dependency injection file (aka, "beans") :
applicationContext.xml
and I need to name to be dynamic, not hard coded.
String myValue = "DefaultEnvVarValue";
String envValue = System.getenv("MYENVVARIABLENAME");
if (null != envValue )
{
myValue=envValue;
}
String topLevelAppContextFileName = "applicationContext." + myValue + ".xml";
Without springboot, I would do this:
ApplicationContext context = new ClassPathXmlApplicationContext(topLevelAppContextFileName);
Is there a way to pull this off with SpringBoot?
I found PropertySourcesPlaceholderConfigurer for property files, but cannot find anything for the dependency injection.
Sidenote:
Before I get a "xml bad" comment, most of my dependencies are annotation based. But I'm making a framework for others to use, and therefore I need a handful of them to be xml-driven.....aka, I have a legit reason to have some of the DI be xml driven.
This could work -
Config
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext ac) {
ac = new ClassPathXmlApplicationContext(topLevelAppContextFileName);
}
}
Main
public static void main(String args[]) {
new SpringApplicationBuilder(Application.class)
.initializers(new DemoApplicationContextInitializer())
.run(
}
For future readers, I ended up doing this:
#SpringBootApplication
#ImportResource({"classpath*:applicationContext.xml"})
public class MySpringBootApplication {
public static void main(String[] args) {
try {
URL resource = MySpringBootApplication.class.getResource("/applicationContext.xml");
if (null == resource || StringUtils.isBlank(resource.getPath())) {
throw new FileNotFoundException("applicationContext.xml not found. The entry dependency injection file must be applicationContext.xml");
}
org.springframework.context.ConfigurableApplicationContext applicationContext = SpringApplication.run(MySpringBootApplication.class, args);
And then I put the "dynamic" part in the inside applicationContext.xml file.
Note the ":" delimiter that will allow a default value if the environment variable does not exist.
<?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:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util.xsd">
<import resource="projectContext.${MYENVVARIABLENAME:DefaultEnvVarValue}.xml"/>
That was simpler to implement, even though I technically have 2 files, instead of one.
So if the environment variable does not exist, it will default to importing the second file called:
projectContext.DefaultEnvVarValue.xml

How to parse Spring Integration HTTP gateway response into a Bean?

I've been trying to get a simple integration workflow for practice purposes. The thing is I just started working with Spring and I'm having a hard time understanding Integration and how it works.
Right now I've got a really simple backend app with Spring MVC that returns
[
{"id":1,"name":"Series test","synopsis":"Testing reading items from JSON.","imageUrl":"http://some.where/images/some_image.png"},
{"id":2,"name":"Arrow","synopsis":"Some guy in a hood shooting arrows to some guys with superpowers.","imageUrl":"http://some.where/images/some_image.png"},
{"id":3,"name":"Primeval","synopsis":"Some guys with guns killing dinosaurs and lots of infidelity.","imageUrl":"http://some.where/images/some_image.png"},
{"id":4,"name":"Dr. Who","synopsis":"It's bigger on the inside.","imageUrl":"http://some.where/images/some_image.png"},
{"id":5,"name":"Fringe","synopsis":"Weird things happen.","imageUrl":"http://some.where/images/some_image.png"},
{"id":6,"name":"Monster Hunter Freedom Unite","synopsis":"Wait. This is a game.","imageUrl":"http://some.where/images/some_image.png"}
]
to http://localhost:9000/api/series/findAll and a runnable Spring project that, with Integration, attempts to recover that data and convert it to a Series (bean with the same properties as the JSON) array.
If I don't add a reply-channel to the outbound-gateway everything works just fine. But when I send it to another channel to parse it into a Series object I start getting "Dispatcher has no subscribers" on the new channel. It makes sense but it leaves me not knowing how to proceed now.
My project files, apart from Series, look like this right now:
Startup.java
package com.txus.integration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
import java.util.concurrent.Future;
public class Startup {
#Autowired
RequestGateway requestGateway;
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration-components.xml");
RequestGateway requestGateway = context.getBean(RequestGateway.class);
Future<String> promise = requestGateway.getSeries("");
while (!promise.isDone()) {
Thread.sleep(1000);
}
String response = promise.get();
printReadable(response);
context.close();
System.exit(0);
}
public static void printReadable(String string) {
String separator = "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =";
System.out.println("\n" + separator + "\n" + string + "\n" + separator + "\n");
}
public static void printReadable(List<String> strings) {
for (String string : strings) printReadable(string);
}
}
RequestGateway
package com.txus.integration;
import com.txus.entities.Series;
import org.springframework.integration.annotation.Gateway;
import java.util.concurrent.Future;
public interface RequestGateway {
#Gateway(requestChannel="responseChannel")
Future<String> getSeries(String jsonString);
#Gateway(requestChannel="responseChannel")
Future<String> getSeries(Series series);
}
integration-components.xml
<beans:beans
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:http="http://www.springframework.org/schema/integration/http"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.1.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.txus"/>
<!-- START: Spring Integration -->
<!-- Integration: Channels -->
<channel id="requestChannel"/>
<channel id="responseChannel"/>
<channel id="failedChannel"/>
<!-- Integration: Loggers -->
<logging-channel-adapter
id="payloadLogger" level="DEBUG" expression="'### Message [' + headers.id + '] payload: ' + payload"/>
<logging-channel-adapter
id="headersLogger" level="DEBUG" expression="'### Message [' + headers.id + '] headers: ' + headers"/>
<!-- Integration: Flow -->
<gateway
service-interface="com.txus.integration.RequestGateway"
default-request-timeout="5000" async-executor="executor">
<method name="getSeries" request-channel="inputChannel"/>
</gateway>
<task:executor id="executor" pool-size="100"/>
<payload-type-router input-channel="inputChannel" default-output-channel="failedChannel">
<mapping type="java.lang.String" channel="requestChannel"/>
<mapping type="com.txus.entities.Series" channel="objectToJSONChannel"/>
</payload-type-router>
<object-to-json-transformer
id="objectToJsonTransformer" input-channel="objectToJSONChannel" output-channel="requestChannel"/>
<http:outbound-gateway
http-method="GET"
expected-response-type="java.lang.String"
url="http://localhost:9000/api/series/findAll"
request-channel="requestChannel"
reply-channel="jsonToSeries"
reply-timeout="30000"/>
<map-to-object-transformer
input-channel="jsonToSeries" output-channel="responseChannel" type="com.txus.entities.Series"/>
<!-- END: Spring Integration -->
</beans:beans>
You have an issue with the last component where you configure output-channel="responseChannel". There is just nothing which is subscribed to that channel.
I see your #Gateway config on the matter, but it is a bit wrong. XML configuration has a precedence over annotations there. Hence the requestChannel in the end is exactly inputChannel.
If you'd like to send the result of <map-to-object-transformer> to the responseChannel and accept it as a return from the RequestGateway invocation, you should specify that responseChannel as a reply-channel on the gateway configuration.
From other side you just don't need it there and the TemporaryReplyChannel comes to the rescue.
Please, refer for more information to the Spring Integration Manual.

What is BeanNameViewResolver?

I read the documentation here, but I think that the Spring documentation is sometimes complex and hard to understand, so I need a little explanation about BeanNameViewResolver.
Can I get a code example?
As explained in the documentation,BeanNameViewResolver resolves Views declared as beans. Most of the time you need it for some special-purpose views.
For example, we need to render an Excel spreadsheet.
For the Excel generation you will Apache POI
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
So, you subclass AbstractExcelView and implement your custom logic to render a spreadsheet based on model values.
public class CustomExcelView extends AbstractExcelView {
#Override
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
Map<String,String> revenueData = (Map<String,String>) model.get("revenueData");
//create a wordsheet
HSSFSheet sheet = workbook.createSheet("Revenue Report");
HSSFRow header = sheet.createRow(0);
header.createCell(0).setCellValue("Month");
header.createCell(1).setCellValue("Revenue");
int rowNum = 1;
for (Map.Entry<String, String> entry : revenueData.entrySet()) {
//create the row data
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(entry.getKey());
row.createCell(1).setCellValue(entry.getValue());
}
}
}
and the controller simply adds the data
package com.example;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/excelview")
public class ExcelController {
public String getExcel(Model model){
Map<String,String> revenueData = new HashMap<String,String>();
revenueData.put("Jan-2010", "$100,000,000");
revenueData.put("Feb-2010", "$110,000,000");
revenueData.put("Mar-2010", "$130,000,000");
revenueData.put("Apr-2010", "$140,000,000");
revenueData.put("May-2010", "$200,000,000");
model.addAttribute("revenueData",revenueData);
return "myExcelView";
}
}
Then declaring an BeanNameViewResolver makes it available to controllers: when controller returns String with view name myExcelView, your spreadsheet will be rendered.
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.example" />
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="myExcelView" class="com.example.CustomExcelView" />
</beans>

Spring TypeConverter fails on Camel RouteBuilder subclass

In an attempt to install my component on karaf I get the following error:
Caused by: org.apache.camel.CamelException: Cannot find any routes with this RouteBuilder reference: RouteBuilderRef[logparserRouteBean]
I've narrowed it down to a conversion error in AbstractBeanFactory using the SimpleTypeConverter as returned by the getTypeConverter().
Given that PerformanceLogRoute extends org.apache.camel.builder.RouteBuilder, how can the convertion fail??
Suggestions, and ideas to any solution is greatly appreciated.
UPDATE
package no.osl.cdms.profile.routes;
import no.osl.cdms.profile.api.TimeMeasurement;
import no.osl.cdms.profile.factories.EntityFactory;
import no.osl.cdms.profile.log.TimeMeasurementEntity;
import no.osl.cdms.profile.parser.LogLineRegexParser;
import org.apache.camel.builder.RouteBuilder;
import java.util.Map;
public class PerformanceLogRoute extends RouteBuilder {
public static final String PERFORMANCE_LOG_ROUTE_ID = "PerformanceLogRoute";
private static final String LOG_DIRECTORY = "C:/data";
private static final String LOG_FILE = "performance.log";
private static final int DELAY = 0;
private LogLineRegexParser logLineRegexParser = new LogLineRegexParser();
private EntityFactory entityFactory = EntityFactory.getInstance();
private static final String LOG_FILE_ENDPOINT = "stream:file? fileName="+LOG_DIRECTORY +"/"+LOG_FILE+"&scanStream=true&scanStreamDelay=" + DELAY;
private static final String DATABASE_ENDPOINT = "jpa:";
#Override
public void configure() throws Exception{
fromF(LOG_FILE_ENDPOINT, LOG_DIRECTORY, LOG_FILE, DELAY)
.convertBodyTo(String.class) // Converts input to String
.choice().when(body().isGreaterThan("")) // Ignores empty lines
.bean(logLineRegexParser, "parse") // Parses log entry into String map
.bean(entityFactory, "createTimemeasurement") // Parses log entry into database format
.split(body())
.choice().when(body().isNotNull())
.toF(DATABASE_ENDPOINT, body().getClass().toString())
.routeId(PERFORMANCE_LOG_ROUTE_ID);
}
public String toString() {
return PERFORMANCE_LOG_ROUTE_ID;
}
}
The 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:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="logparserRouteBean" class="no.osl.cdms.profile.routes.PerformanceLogRoute" />
<camelContext id="cdms-core-camel-context" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="logparserRouteBean" />
</camelContext>
</beans>
This is what I found at this moment. From what I remember it is identical to what caused the error, but I'll double check in the morning.

Spring Integration with Twitter Issue with Authentication

I am trying to post a message to my twitter account using Spring Integration with Twitter with a standalone program on my windows XP machine. But I am getting the following error -
WARNING: POST request for "https://api.twitter.com/1/statuses/update.json" resulted in 401 (Unauthorized); invoking error handler
Exception in thread "main" org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.twitter.outbound.StatusUpdatingMessageHandler#0]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
at com.skilledmonster.spring.integration.twitter.TwitterOutbound.main(TwitterOutbound.java:20)
Caused by: org.springframework.social.RevokedAuthorizationException: The authorization has been revoked. Reason: Unknown
at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleClientErrors(TwitterErrorHandler.java:96)
at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleError(TwitterErrorHandler.java:58)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:415)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:294)
at org.springframework.social.twitter.api.impl.TimelineTemplate.updateStatus(TimelineTemplate.java:236)
at org.springframework.social.twitter.api.impl.TimelineTemplate.updateStatus(TimelineTemplate.java:224)
at org.springframework.integration.twitter.outbound.StatusUpdatingMessageHandler.handleMessageInternal(StatusUpdatingMessageHandler.java:57)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
... 6 more
Here is my code -
twitter-outbound.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/integration/twitter
http://www.springframework.org/schema/integration/twitter/spring-integration-twitter-2.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan
base-package="com.apress.prospringintegration.social.twitter" />
<context:property-placeholder location="/twitter.properties" />
<int:channel id="twitterOutbound" />
<twitter:outbound-channel-adapter twitter-template="twitterTemplate" channel="twitterOutbound" />
<bean id="twitterTemplate"
class="org.springframework.social.twitter.api.impl.TwitterTemplate">
<constructor-arg value="${twitter.consumer-key}" />
<constructor-arg value="${twitter.consumer-secret}" />
<constructor-arg value="${twitter.access-token}" />
<constructor-arg value="${twitter.access-token-secret}" />
</bean>
</beans>
TwitterConfigurationTemplate.java
package com.skilledmonster.spring.integration.twitter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.social.twitter.api.impl.TwitterTemplate;
#Configuration
public class TwitterConfigurationTemplate {
#Value("${consumer-key}")
private String consumerKey;
#Value("${consumer-secret}")
private String consumerSecret;
#Value("${access-token}")
private String accessToken;
#Value("${access-token-secret}")
private String accessTokenSecret;
#Bean
public TwitterTemplate twitterTemplate() {
TwitterTemplate twitterOperations =
new TwitterTemplate(
consumerKey, consumerSecret, accessToken, accessTokenSecret);
return twitterOperations;
}
}
TwitterOutbound.java
package com.skilledmonster.spring.integration.twitter;
import java.util.Calendar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.message.GenericMessage;
public class TwitterOutbound {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/twitter-outbound.xml", TwitterOutbound.class);
MessageChannel input = context.getBean("twitterOutbound", MessageChannel.class);
Message<String> message = new GenericMessage<String>("Testing new Twitter samples for #springintegration"+Calendar.getInstance().getTimeInMillis());
input.send(message);
}
}
twitter.properties
twitter.consumer-key=onj5cG1P9pe7n9qA8UI4EA
twitter.consumer-secret=2l7hqMafKYaTkVBW3YfuBfGdzCtmICOJwjOOCEeQ
twitter.access-token=792995125-dXmN1Pbw7sE4WttvAbX7ssxEn4lHaVd6uOX3IMxk
twitter.access-token-secret=a1EuvvONcphdqXpfJVjCdaIBDlMZSUL5pgimWuEtg
FYI - I did test my twitter token and key with twitter4j and it seems to be posting the message to twitter successfully.
Here is my code with twitter4j -
OAuthSetup.java
package com.skilledmonster.spring.integration.twitter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Calendar;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
public class OAuthSetup {
/**
* #param args
*/
public static void main(String args[]) throws Exception {
// The factory instance is re-useable and thread safe.
Twitter twitter = new TwitterFactory().getInstance();
//insert the appropriate consumer key and consumer secret here
twitter.setOAuthConsumer("onj5cG1P9pe7n9qA8UI4EA",
"2l7hqMafKYaTkVBW3YfuBfGdzCtmICOJwjOOCEeQ");
RequestToken requestToken = twitter.getOAuthRequestToken();
AccessToken accessToken = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (null == accessToken) {
System.out.println("Open the following URL and grant access to your account:");
System.out.println(requestToken.getAuthorizationURL());
System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
String pin = br.readLine();
try{
if(pin.length() > 0){
accessToken = twitter.getOAuthAccessToken(requestToken, pin);
}else{
accessToken = twitter.getOAuthAccessToken();
}
} catch (TwitterException te) {
if(401 == te.getStatusCode()){
System.out.println("Unable to get the access token.");
}else{
te.printStackTrace();
}
}
}
//persist to the accessToken for future reference.
System.out.println(twitter.verifyCredentials().getId());
System.out.println("token : " + accessToken.getToken());
System.out.println("tokenSecret : " + accessToken.getTokenSecret());
//storeAccessToken(twitter.verifyCredentials().getId() , accessToken);
Status status = twitter.updateStatus("Testing new Twitter samples for springintegration # "+Calendar.getInstance().getTimeInMillis());
System.out.println("Successfully updated the status to [" + status.getText() + "].");
System.exit(0);
}
}
Can anyone suggest me what is going wrong here?
The token you are using to access Twitter has been revoked, or possibly not valid for the consumer id / application id you are using.
org.springframework.social.RevokedAuthorizationException: The authorization has been revoked
You will need to perform a new authorisation to obtain a token and secret for use with your application, or alternatively, on the twitter application configuration page (https://dev.twitter.com/apps/) you can generate a token specifically for your personal usage. This is useful for testing an app conveniently without having to perform OAuth.
I figured the issue was with the empty spaces in the key values in the properties file :-)
Here is a full example on my blog.

Resources