I have a SOAP client created in spring boot and I'm logging all SOAP messages, but the new version of LoggingFeature (org.apache.cxf.ext.logging.LoggingFeature) shows payload on one line even though I'm using prettyLogging and deprecated version of this class (org.apache.cxf.feature.LoggingFeature) formats payload when used prettyLogging.
When used deprecated version of class - format I want (random example):
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Envelope xmlns="URL" xmlns:ns2="URL">
<Service ID="SERVICE"/>
<Inquirer ID="ID" CorrelationID="ID" Version="1.0" Timestamp="Timestamp"/>
<Data Content="xml">
<ns2:Request>
<ns2:FILE>ID</ns2:FILE>
<ns2:ACTION>ACTION</ns2:ACTION>
</ns2:Request>
</Data>
<File>
<FileDescription ID="ID"/>
</File>
</Envelope>
</soap:Body>
</soap:Envelope>
When used new version:
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Envelope xmlns="URL" xmlns:ns2="URL"><Service ID="SERVICE"/><Inquirer ID="ID" CorrelationID="ID" Version="1.0" Timestamp="Timestamp"/><Data Content="xml"><ns2:Request><ns2:FILE>ID</ns2:FILE> <ns2:ACTION>ACTION</ns2:ACTION></ns2:Request></Data><File><FileDescription ID="ID"/></File></Envelope></soap:Body></soap:Envelope>
My configuration class:
import javax.annotation.PostConstruct;
import org.apache.cxf.ext.logging.AbstractLoggingInterceptor;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.ext.logging.LoggingInInterceptor;
import org.apache.cxf.ext.logging.LoggingOutInterceptor;
import org.apache.cxf.bus.spring.SpringBus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class CxfConfig {
#Autowired
private SpringBus springBus;
#PostConstruct
public void activateLoggingFeature() {
springBus.getInInterceptors().add(logInInterceptor());
springBus.getInFaultInterceptors().add(logInInterceptor());
springBus.getOutInterceptors().add(logOutInterceptor());
springBus.getOutFaultInterceptors().add(logOutInterceptor());
}
#Bean
public LoggingFeature loggingFeature() {
LoggingFeature logFeature = new LoggingFeature();
logFeature.setPrettyLogging(true);
logFeature.initialize(springBus);
springBus.getFeatures().add(logFeature);
return logFeature;
}
public AbstractLoggingInterceptor logInInterceptor() {
LoggingInInterceptor logInInterceptor = new LoggingInInterceptor();
logInInterceptor.setLimit(-1);
logInInterceptor.setPrettyLogging(true);
logInInterceptor.setLogBinary(true);
logInInterceptor.setLogMultipart(true);
return logInInterceptor;
}
public AbstractLoggingInterceptor logOutInterceptor() {
LoggingOutInterceptor logOutInterceptor = new LoggingOutInterceptor();
logOutInterceptor.setPrettyLogging(true);
logOutInterceptor.setLimit(-1);
logOutInterceptor.setLogBinary(true);
logOutInterceptor.setLogMultipart(true);
return logOutInterceptor;
}
}
Related
Linebreaks ("\n" or "\r") are been stripped out from gzip response body, when using response compression configuration (as below) in Spring Cloud Open Feign. There are no errors raised. Linebreaks are just been replace by an empty string "". The response has the correct "content-encoding: gzip" header, and a well formed gzipped body content.
Does someone has a clue? It seems a issue for me as I opened here spring-cloud-openfeign/issue400
feign.compression.response.enabled: true
feign.compression.response.useGzipDecoder: true
# Same behaviour using Apache Http as client
feign.httpclient.enabled: true
SpringCloudFeignClient.java
package springcloudfeigngzip;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
#FeignClient(name = "SpringCloudFeignClient", url = "http://localhost:8082")
public interface SpringCloudFeignClient {
#GetMapping(value = "/gzip")
String getGzippedString();
}
ApplicationTest.java:
package springcloudfeigngzip;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
#SpringBootTest
#AutoConfigureWireMock(port = 8082)
class ApplicationTest {
#Autowired
private SpringCloudFeignClient springCloudFeignClient;
#Test
void success_GzipOneLine() {
stubFor(get(urlEqualTo("/gzip")).withHeader("Accept-Encoding", containing("gzip"))
.willReturn(aResponse().withStatus(200).withBody("lineone")));
String response = springCloudFeignClient.getGzippedString();
assertEquals("lineone", response); //success
}
#Test
void fail_GzipLineBreak() {
stubFor(get(urlEqualTo("/gzip")).withHeader("Accept-Encoding", containing("gzip"))
.willReturn(aResponse().withStatus(200).withBody("lineone\nlinetwo")));
String response = springCloudFeignClient.getGzippedString();
assertEquals("lineone\nlinetwo", response); //fail!
}
}
bootstrap.yml:
feign:
compression:
response:
enabled: true
useGzipDecoder: true
Versions:
org.springframework.boot: 2.3.3.RELEASE
org.springframework.cloud: Hoxton.SR8
Full project here:
https://github.com/spring-cloud/spring-cloud-openfeign/files/5147346/spring-cloud-feign-gzip.zip
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);
}
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.
I am trying to marshal with jaxb an object which contains an Image, and afterwards unmarshalling it (i.e. save/load).
Is there a way to store that image?
I am trying to create a function which returns the byte array describing the swt.image imagedata, but once I marked it as an #XmlElement, the process of storing it fails throwing an Exception like this:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
JAXB annotation is placed on a method that is not a JAXB property
this problem is related to the following location:
at #javax.xml.bind.annotation.XmlElement()
Also, I have tested to convert the SWT.Image to a AWT.BufferedImage, but I still get the same Exception.
Your exception indicates that you have placed an annotation on a method that isn't an accessor (get/set method). Below is an example using a java.awt.Image property:
Root
package forum9094655;
import java.awt.Image;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Root {
private Image image;
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
}
Demo
package forum9094655;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Root root = new Root();
Image image = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
root.setImage(image);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<image>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mNgYGAAAAAEAAHI6uv5AAAAAElFTkSuQmCC</image>
</root>
I'm trying to implement loading Resource Bundles for JSF application from DB, following the sample: internationalization in JSF with ResourceBundle entries which are loaded from database
For the test I coded getItSomehow() just as create HashMap and fill it with key "hello_world" and value "["+locale+"]"+"hello world"
The sample works fine when I deploy it on Glassfish3.
But when I use WebSphere AS 7, the jsf page is displayed correctly only for the first time. Opening the jsf page in other browsers (with other prefered language selected) I receive the respond always in the locale of first run.
While debugging, I found the difference in implementation of ResourceBundle.java: Glassfish uses this class provided in rt.jar of the JDK1.6; but WebSphere has this class inside java.util.jar
The ResourceBundle (of WebSphere) called from ApplicationResourceBundle.getResourceBundle() calls handleGetBundle() and finally invokes my.i18n.DbResourceBundle$DBControl.newBundle() .
Called second (and further) time with different locale it doesn't invoke my override but just returns the same bundle created for first locale.
The question: is it possible to code internalizable jsf web-application deployed on WebSphere AS 7.0.07, not digging nor hacking into internals of the AS?
(environment: Windows XP, WebSphere AS 7.0.0.7, jdk1.6.0_24, jsf 2.1.4)
You can provide a specific implementation of ResourceBundle.
Here an example that gets the current locale each time JSF invokes the ResourceBundle methods:
package my.company.jsf.util;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
public class MyBundle extends ResourceBundle {
private static final Map<Locale, ResourceBundle> RB_CACHE = new HashMap<Locale, ResourceBundle>();
private static final String BUNDLE_NAME = "my-messages";
public MyBundle() {
}
#Override
public Enumeration<String> getKeys() {
ResourceBundle rb = getResourceBundle();
final Iterator<String> it = rb.keySet().iterator();
return new Enumeration<String>() {
#Override
public boolean hasMoreElements() {
return it.hasNext();
}
#Override
public String nextElement() {
return it.next();
}
};
}
#Override
protected Object handleGetObject(String key) {
ResourceBundle rb = getResourceBundle();
return rb.getObject(key);
}
private ResourceBundle getResourceBundle() {
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
ResourceBundle rb = RB_CACHE.get(locale);
if (rb == null) {
rb = ResourceBundle.getBundle(BUNDLE_NAME, locale);
RB_CACHE.put(locale, rb);
}
return rb;
}
}
and in your faces-config.xml put:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<resource-bundle>
<base-name>my.company.jsf.util.MyBundle</base-name>
<var>MSG</var>
</resource-bundle>
</application>
</faces-config>
We had your same problem and this solution worked for us with Windows Server 2008, WebSphere AS 7.0.0.19, jdk1.6.0_29, jsf 2.1.5