How do I print the entire stack trace using java.util.Logger? (without annoying Netbeans).
The question should've originally specified staying within Java SE. Omitting that requirment was an error on my part.
-do-compile:
[mkdir] Created dir: /home/thufir/NetBeansProjects/rainmaker/build/empty
[mkdir] Created dir: /home/thufir/NetBeansProjects/rainmaker/build/generated-sources/ap-source-output
[javac] Compiling 13 source files to /home/thufir/NetBeansProjects/rainmaker/build/classes
[javac] /home/thufir/NetBeansProjects/rainmaker/src/model/TelnetEventProcessor.java:44: error: 'void' type not allowed here
[javac] log.severe(npe.printStackTrace(System.out));
[javac] ^
[javac] 1 error
BUILD FAILED
code with the error:
package model;
import java.util.Observable;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TelnetEventProcessor extends Observable {
private static Logger log = Logger.getLogger(TelnetEventProcessor.class.getName());
private String string = null;
public TelnetEventProcessor() {
}
private void stripAnsiColors() {
Pattern regex = Pattern.compile("\\e\\[[0-9;]*m");
Matcher regexMatcher = regex.matcher(string);
string = regexMatcher.replaceAll(""); // *3 ??
}
public void parse(String string) {
this.string = string;
ifs();
}
// [\w]+(?=\.)
private void ifs() {
log.fine("checking..");
if (string.contains("confusing the hell out of")) {
Pattern pattern = Pattern.compile("[\\w]+(?=\\.)"); //(\w+)\.
Matcher matcher = pattern.matcher(string);
String enemy = null;
GameData data = null;
while (matcher.find()) {
enemy = matcher.group();
}
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
log.severe(npe.printStackTrace(System.out));
}
} else if (string.contains("Enter 3-letter city code:")) {
log.fine("found enter city code");
} else {
}
}
}
see also:
https://stackoverflow.com/a/7100975/262852
The severe method is only used to log severe messages without associated throwable information. If you need to log throwable information then you should use the log method instead:
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
log.log(Level.SEVERE, npe.getMessage(), npe);
}
Why don't you put the exception in the logger?
You can use this method :
logger.log(Level level, String msg, Throwable thrown)
Maybe a duplicated question? Java - Need a logging package that will log the stacktrace
Below the explanation from the given url
Using log4j
this is done with:
logger.error("An error occurred", exception);
The first argument is a message to be displayed, the second is the
exception (throwable) whose stacktrace is logged.
Another option is commons-logging,
where it's the same:
log.error("Message", exception);
With java.util.logging
this can be done via:
logger.log(Level.SEVERE, "Message", exception);
You don't explicitly print the stack trace; Throwables have stack traces attached to them, and you can pass a Throwable to the log methods:
log(Level level, String msg, Throwable thrown)
You could use Apache ExceptionUtils. In your case
try {
data = new GameData.Builder().enemy(enemy).build();
log.fine("new data object\t\t" + data.getEnemy());
setChanged();
notifyObservers(data);
} catch (NullPointerException npe) {
logger.info(**ExceptionUtils.getFullStackTrace(npe)**);
}
You should redirect the System.err to the logger, the process is not too simple but you can use this code:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LogOutputStream extends ByteArrayOutputStream {//java.io.OutputStream {
private String lineSeparator;
private Logger logger;
private Level level;
public LogOutputStream(Logger logger, Level level) {
super();
this.logger = logger;
this.level = level;
this.lineSeparator = System.getProperty("line.separator");
}
#Override
public void flush() throws IOException {
String record;
synchronized (this) {
super.flush();
record = this.toString();
super.reset();
if ((record.length() == 0) || record.equals(this.lineSeparator)) {
// avoid empty records
return;
}
this.logger.logp(this.level, "", "", record);
}
}
}
And The code to set this (that should called the when you first create the logger
Logger logger = Logger.getLogger("Exception");
LogOutputStream los = new LogOutputStream(logger, Level.SEVERE);
System.setErr(new PrintStream(los, true));
This will redirect the System.err stream to the logger.
You can also try to use ExceptionUtils from apache commons
The exception is due to the printstacktrace method being void, meaning it doesn't return anything. You are trying to do:
log.severe(npe.printStackTrace(System.out));
My guess is that the severe method needs a String and not void.
Related
Tried the following:
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.spi.FileTypeDetector;
import org.apache.tika.Tika;
import org.apache.tika.mime.MimeTypes;
/**
*
* #author kiriti.k
*/
public class TikaFileTypeDetector {
private final Tika tika = new Tika();
public TikaFileTypeDetector() {
super();
}
public String probeContentType(Path path) throws IOException {
// Try to detect based on the file name only for efficiency
String fileNameDetect = tika.detect(path.toString());
if (!fileNameDetect.equals(MimeTypes.OCTET_STREAM)) {
return fileNameDetect;
}
// Then check the file content if necessary
String fileContentDetect = tika.detect(path.toFile());
if (!fileContentDetect.equals(MimeTypes.OCTET_STREAM)) {
return fileContentDetect;
}
// Specification says to return null if we could not
// conclusively determine the file type
return null;
}
public static void main(String[] args) throws IOException {
Tika tika = new Tika();
// expects file path as the program argument
if (args.length != 1) {
printUsage();
return;
}
Path path = Paths.get(args[0]);
TikaFileTypeDetector detector = new TikaFileTypeDetector();
// Analyse the file - first based on file name for efficiency.
// If cannot determine based on name and then analyse content
String contentType = detector.probeContentType(path);
System.out.println("File is of type - " + contentType);
}
public static void printUsage() {
System.out.print("Usage: java -classpath ... "
+ TikaFileTypeDetector.class.getName()
+ " ");
}
}
The above program is checking based on file extension only. How do I make it to check content type also(mime) and then determine the type. I am using tika-app-1.8.jar in netbean 8.0.2. What am I missing?
The code checks the file extension first and returns the MIME type based on that, if it finds a result. If you want it to check the content first, just switch the two statements:
public String probeContentType(Path path) throws IOException {
// Check contents first
String fileContentDetect = tika.detect(path.toFile());
if (!fileContentDetect.equals(MimeTypes.OCTET_STREAM)) {
return fileContentDetect;
}
// Try file name only if content search was not successful
String fileNameDetect = tika.detect(path.toString());
if (!fileNameDetect.equals(MimeTypes.OCTET_STREAM)) {
return fileNameDetect;
}
// Specification says to return null if we could not
// conclusively determine the file type
return null;
}
Be aware that this may have huge performance impact.
You can use Files.probeContentType(path)
I built a servlet that compiles java code and returns compilation errors (if any).
I'm calling it from an html form where I type the code. The thing is, whenever I use the "+" operator for arithmetic addition or to concatenate strings, it just doesn't like it.
This is my servlet class:
#WebServlet("/compiler")
public class Compiler extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
StringBuffer sb = new StringBuffer();
String code = request.getParameter("codeToCompile").toString();
String results = this.compile(code);
sb.append(results);
out.println(sb);
}
private String compile(String codeToCompile){
String compilationResults = null;
String toCompile = "class test {" + codeToCompile + "}";
/*Creating dynamic java source code file object*/
SimpleJavaFileObject fileObject = new JavaObjectFromString ("ejercicio", toCompile);
JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
/*Instantiating the java compiler*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
/*Create a diagnostic controller, which holds the compilation problems*/
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
/*get a standard file manager from compiler, this file manager helps us to customize how a compiler reads and writes to files*/
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(diagnostics, null, null);
/* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
/*Prepare any compilation options to be used during compilation
//In this example, we are asking the compiler to place the output files under bin folder.*/
String[] compileOptions = new String[]{"-d", "c:"} ;
Iterable<String> compilationOptions = Arrays.asList(compileOptions);
/*Create a compilation task from compiler by passing in the required input objects prepared above*/
CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, compilationOptions, null, compilationUnits) ;
/*Perform the compilation by calling the call method on compilerTask object.*/
boolean status = compilerTask.call();
/*On compilation failure, we can use the diagnostic collector to read the error messages and log them in specific format.*/
if (!status){//If compilation error occurs
/*Iterate through each compilation problem and print it*/
for (#SuppressWarnings("rawtypes") Diagnostic diagnostic : diagnostics.getDiagnostics()){
compilationResults = "ERROR IN LINE "+ diagnostic.getLineNumber() + ": " + diagnostic.getMessage(new Locale(null));
}
}
else
{
compilationResults = "SUCCESS";
}
/*Finally close the fileManager instance to flush out anything that is there in the buffer.*/
try {
stdFileManager.close() ;//Close the file manager
} catch (IOException e) {
e.printStackTrace();
}
return compilationResults;
}
}
It instantiates a class called "JavaObjectFromString" which looks like this:
public class JavaObjectFromString extends SimpleJavaFileObject{
private String contents;
private String name;
public JavaObjectFromString(String className, String contents){
super(URI.create(className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.contents = contents;
this.name = className;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return this.contents;
}
}
Everything works fine until I attempt to use the + operator either with Strings or with numbers.
I've been testing different scenarios. For example, some code like this:
String someText = "test" + "test";
trows Error on line 1: ';' expected. Also happens when I use the operator inside a method:
public String testMethod(){
return "test" + "test";
}
If I then try:
public String testMethod(String one, String two){
return one + two;
}
it throws Error on line 2: not a statement
If I do:
public int someNumber = 12 + 345;
I also get Error on line 1: ';' expected
Where in my servlet code am I breaking the + operator??
SOLVED. The problem was not in how the servlet handles the code but in how it was sent using ajax to post the form contents. All I needed was to encode the text before sending it:
ajaxObject.send('codigo='+encodeURIComponent(codigo));
I have a problem regarding java.lang.NoSuchMethodError. This program is about Compiler API (JSR 199). When I create a prototype for this it run work, but when I try to make it to become library it throw NoSuchMethodError Exception.
Here is the First Prototype:
public class DynaCompTest {
public static void main(String[] args) {
String fullName = "HelloWorld";
StringBuilder sourceCode = new StringBuilder();
sourceCode.append("public class HelloWorld {\n")
.append("\tpublic static void main(String[] args) {\n")
.append("\t\tSystem.out.println(\"Hello World\")\n")
.append("\t}\n")
.append("}");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
List<JavaFileObject> jFiles = new ArrayList<>();
jFiles.add(new CharSequenceJavaFileObject(fullName, sourceCode));
compiler.getTask(null, fileManager, diagnostics, null, null, jFiles).call();
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s\n", diagnostic.getLineNumber(), diagnostic);
}
}
}
public class CharSequenceJavaFileObject extends SimpleJavaFileObject {
private CharSequence content;
public CharSequenceJavaFileObject(String className, CharSequence content) {
super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.content = content;
}
#Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return content;
}
}
public class ClassFileManager extends ForwardingJavaFileManager {
private JavaClassObject jClassObject;
public ClassFileManager(StandardJavaFileManager standardManager) {
super(standardManager);
}
#Override
public ClassLoader getClassLoader(Location location) {
return new SecureClassLoader() {
#Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = jClassObject.getBytes();
return super.defineClass(name, jClassObject.getBytes(), 0, b.length);
}
};
}
#Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
jClassObject = new JavaClassObject(className, kind);
return jClassObject;
}
}
public class JavaClassObject extends SimpleJavaFileObject {
protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
public JavaClassObject(String name, Kind kind) {
super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);
}
public byte[] getBytes() {
return bos.toByteArray();
}
#Override
public OutputStream openOutputStream() {
return bos;
}
}
I changed the DynaCompTest become DynamicCompiler for the library:
public class DynamicCompiler {
private JavaCompiler compiler;
private JavaFileManager fileManager;
private List<JavaFileObject> jFiles;
private DiagnosticCollector<JavaFileObject> diagnostics;
public DiagnosticCollector<JavaFileObject> getDiagnostics() {
return diagnostics;
}
public DynamicCompiler(String className, StringBuilder sourceCode) {
compiler = ToolProvider.getSystemJavaCompiler();
fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
diagnostics = new DiagnosticCollector<>();
jFiles = new ArrayList<>();
jFiles.add(new CharSequenceJavaFileObject(className, sourceCode));
}
public boolean doCompilation() {
return compiler.getTask(null, fileManager, diagnostics, null, null, jFiles).call();
}
}
And I created Second Prototype to test the library:
public class Compiler {
private static StringBuilder sourceCode = new StringBuilder();
public static void main(String[] args) {
boolean status;
sourceCode.append("public class HelloWorld {\n")
.append("\tpublic static void main(String[] args) {\n")
.append("\t\tSystem.out.println(\"Hello World\");\n")
.append("\t}\n")
.append("}");
DynamicCompiler compiler = new DynamicCompiler("HelloWorld", sourceCode);
status = compiler.doCompilation();
StringBuilder messages = new StringBuilder();
if (!status) {
for (Diagnostic diagnostic : compiler.getDiagnostics().getDiagnostics()) {
messages.append("Error on line ")
.append(diagnostic.getLineNumber())
.append(" in ")
.append(diagnostic)
.append("\n");
}
} else {
messages.append("BUILD SUCCESSFUL ");
}
System.out.println(messages.toString());
}
}
When I test with code above it run well and print BUILD SUCCESSFUL but when I tried to make it error for example I deleted the semicolon ; like the first prototype, it throw the NoSuchMethodError Exception when access the compiler.getDiagnostics().getDiagnostics() inside the looping.
The question is, why in the First Prototype it run well when try to make an error but when I tried with my own library it become Exception?
Edit
Here is the stacktrace:
/HelloWorld.java:3: error: ';' expected
System.out.println("Hello World")
^
1 error
Exception in thread "main" java.lang.NoSuchMethodError: org.ert.lib.DynamicCompiler.getDiagnostics()Ljavax/tools/DiagnosticCollector;
at org.ert.exp.Compiler.main(Compiler.java:28)
Java Result: 1
It should be like this:
Error on line 3 in /HelloWorld.java:3: error: ';' expected
System.out.println("Hello World")
^
When trying to debug it, it shown an error:
public DiagnosticCollector<JavaFileObject> getDiagnostics() {
return diagnostics; // Set Breakpoint here
}
Here is the error message:
Not able to submit breakpoint LineBreakpoint DynamicCompiler.java : 25, reason: No executable location available at line 25 in class org.ert.lib.DynamicCompiler.
Invalid LineBreakpoint DynamicCompiler.java : 25
Update
Got the problem, this problem will occur if we add the whole project instead build the jar of the library. So when I build the library jar it works. But anyone can explain why this thing happen when I try add the whole project instead the jar file?
Note
I'm using:
JDK 1.7 from Oracle
Netbeans 7.1.1
It seems that you have similar class exists in two different libraries(jars).
e.g.
com.test.Example.class in a.jar
com.test.Example.class in b.jar
Now class loader will load the first first Example.class and it seems that you need class which is there in b.jar. Then it will not throw exception such as NoMethodFound but throw an Exception that NoSuchMethodFound because class still exists in memory but can not find required method.
Such problems can be resolved by changing library order. You need to make required library's order higher. You can do this from the eclipse
Project Setting -> Java Build Path -> Order and Export.
Hope this is helpful.
After I tried with Eclipse Indigo, I found that it works when add the Project or add the jar file. While in Netbeans 7.1.1 will get an error if add the Project, but works if add the jar file.
Maybe it one of the bugs of Netbeans...
Thank you for your attention...
When I compile the code below error occurs:
canot find symbol
location: interface org.apache.commons.logging.Log Log.d(TAG,"JSON parsing error - fix it:" + e.getMessage());`
This is my code:
//convertJSONtoArray
private void convertJSONtoArray(String rawJSON){
try {
JSONObject completeJSONObj = new JSONObject(rawJSON);
String json = completeJSONObj.toString();
Log.d(TAG,json);
JSONObject results = completeJSONObj.getJSONObject("results");
} catch (JSONException e) {
Log.d(TAG,"JSON parsing error - fix it:" + e.getMessage());
}
}
There are two possible reasons:
1. You are using Android
In that case replace the import for Apache Commons Logging Log with:
import android.util.Log;
2. You are developing in normal Java environment
Your import statement at the top of your class includes Apache Commons Logging Log, but the code was definitely not written for Commons Logging.
For Commons Loggig is should look like this:
private static final Log LOG = LogFactory.getLog(NAME_OF_YOUR_CLASS.class);
private void convertJSONtoArray(String rawJSON){
try {
JSONObject completeJSONObj = new JSONObject(rawJSON);
String json = completeJSONObj.toString();
if (LOG.isDebugEnabled()) {
LOG.debug(TAG,json);
}
JSONObject results = completeJSONObj.getJSONObject("results");
} catch (JSONException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(TAG,"JSON parsing error - fix it:" + e.getMessage());
}
}
}
I need all SOAP requests logged in the CommonLogFormat (see http://en.wikipedia.org/wiki/Common_Log_Format), plus the duration (the amount of time it takes to process the request).
What's the best way to do this? It looks like it's possible to configure log4j for Spring WebServices but will it log all the values I'm interested in?
http://pijava.wordpress.com/2009/12/04/spring-webservice-soap-requestresponse-logging-with-log4j/
EDIT: We're actually using SLF4J, not Log4j. Also, it looks like it's possible to do this by configuring the PayloadLoggingInterceptor:
http://static.springsource.org/spring-ws/site/reference/html/server.html#server-endpoint-interceptor
But I am not sure where the log messages will go. I added that interceptor to our interceptors and I don't see any log messages.
For Spring Boot project adding below in application.properties worked for me:
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.ws.client.MessageTracing.sent=DEBUG
logging.level.org.springframework.ws.server.MessageTracing.sent=DEBUG
logging.level.org.springframework.ws.client.MessageTracing.received=TRACE
logging.level.org.springframework.ws.server.MessageTracing.received=TRACE
You can use this to log the raw payload of incoming and outgoing web service calls.. I'm not sure how to log how long the webservice communication took.
<!-- Spring Web Service Payload Logging-->
<logger name="org.springframework.ws.client.MessageTracing">
<level value="TRACE"/>
</logger>
<logger name="org.springframework.ws.server.MessageTracing">
<level value="TRACE"/>
</logger>
Additional details can be found at http://static.springsource.org/spring-ws/site/reference/html/common.html#logging
If you have your own Logging system the following interceptor can be an alternative to log the SOAP messages.
setInterceptors(new ClientInterceptor[]{new ClientInterceptor() {
#Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP RESPONSE ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP response into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
#Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP REQUEST ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP request into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
#Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP FAULT ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP fault into the out stream", e) {
private static final long serialVersionUID = 3538336091916808141L;
};
}
return true;
}
}});
In each handle method you can easily use payload to obtain raw soap messages.
This worked for me. It logs the request message sent and the response received. You could work out the total time taken from the log.
log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE
log4j.logger.org.springframework.ws.client.MessageTracing.received=TRACE
First, SLF4J is just a simple facade. It means you still need a logging framework(e.g. java.util.logging, logback, log4j).
Second, Spring-ws uses Commons Logging interface that is another simple facade like SLF4J.
Finally, you can use below setting to enable Spring-ws message logging functionality.
log4j.logger.org.springframework.ws.client.MessageTracing.sent=DEBUG
log4j.logger.org.springframework.ws.client.MessageTracing.received=TRACE
log4j.logger.org.springframework.ws.server.MessageTracing.sent=DEBUG
log4j.logger.org.springframework.ws.server.MessageTracing.received=TRACE
Include the following in the log4j.properties file...
To log all server-side messages:
log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG
To log all client-side messages:
log4j.logger.org.springframework.ws.client.MessageTracing=TRACE
On the DEBUG level - only the payload root element is logged
On the TRACE level - the entire message content is logged
Lastly to log only the sent or received messages use the .sent or .received at the end of the configurations.
ex : log4j.logger.org.springframework.ws.server.MessageTracing.received=DEBUG
logs the client-side received massages payload root element
returning :
DEBUG WebServiceMessageReceiverHandlerAdapter:114 - Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection#51ad62d9] to [http://localhost:8080/mock-platform/services]
For more info
Add a servlet filter to the spring ws (to move with org.springframework.web.servlet.DispatcherServlet) in web.xml
you can find a filter here
http://www.wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431
inside the filter you can log as you wish
. . .
package com.example.Soap;
import org.springframework.ws.client.WebServiceClientException;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.context.MessageContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class LoggingVonfig implements ClientInterceptor {
#Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP RESPONSE ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP response into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
#Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP REQUEST ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP request into the out stream", e) {
private static final long serialVersionUID = -7118480620416458069L;
};
}
return true;
}
#Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
System.out.println("### SOAP FAULT ###");
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
messageContext.getResponse().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
} catch (IOException e) {
throw new WebServiceClientException("Can not write the SOAP fault into the out stream", e) {
private static final long serialVersionUID = 3538336091916808141L;
};
}
return true;
}
#Override
public void afterCompletion(MessageContext messageContext, Exception e) throws WebServiceClientException {
}
}
. . .
This is logging Configuration class
. . .
package com.example.Soap;
import com.example.Soap.com.example.Soap.Add;
import com.example.Soap.com.example.Soap.AddResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.soap.client.core.SoapActionCallback;
public class CalculatorClient extends WebServiceGatewaySupport {
private static Logger log = LoggerFactory.getLogger(CalculatorClient.class);
public com.example.Soap.com.example.Soap.AddResponse getaddition(com.example.Soap.com.example.Soap.Add addrequest){
com.example.Soap.com.example.Soap.Add add = new com.example.Soap.com.example.Soap.Add();
add.setIntB(addrequest.getIntB());
add.setIntA(addrequest.getIntA());
log.info("----------------------------------------------"+"Inbound Request"+"-----------------------");
com.example.Soap.com.example.Soap.AddResponse addResponse = (com.example.Soap.com.example.Soap.AddResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",add,new SoapActionCallback("http://tempuri.org/Add"));
return addResponse;
}
public com.example.Soap.com.example.Soap.SubtractResponse getSubtract(com.example.Soap.com.example.Soap.Subtract subreq){
com.example.Soap.com.example.Soap.Subtract subtract=new com.example.Soap.com.example.Soap.Subtract();
subtract.setIntA(subreq.getIntA());
subtract.setIntB(subreq.getIntB());
com.example.Soap.com.example.Soap.SubtractResponse subtractResponse=(com.example.Soap.com.example.Soap.SubtractResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",subtract,new SoapActionCallback("http://tempuri.org/Subtract"));
return subtractResponse;
}
public com.example.Soap.com.example.Soap.MultiplyResponse getMultiply(com.example.Soap.com.example.Soap.Multiply multiply)
{
com.example.Soap.com.example.Soap.Multiply multiply1=new com.example.Soap.com.example.Soap.Multiply();
multiply1.setIntA(multiply.getIntA());
multiply1.setIntB(multiply.getIntB());
com.example.Soap.com.example.Soap.MultiplyResponse multiplyResponse=(com.example.Soap.com.example.Soap.MultiplyResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",multiply1,new SoapActionCallback("http://tempuri.org/Multiply"));
return multiplyResponse;
}
public com.example.Soap.com.example.Soap.DivideResponse getDivide(com.example.Soap.com.example.Soap.Divide divide){
com.example.Soap.com.example.Soap.Divide divide1=new com.example.Soap.com.example.Soap.Divide();
divide1.setIntA(divide.getIntA());
divide1.setIntB(divide.getIntB());
com.example.Soap.com.example.Soap.DivideResponse divideResponse=(com.example.Soap.com.example.Soap.DivideResponse) getWebServiceTemplate().marshalSendAndReceive("http://www.dneonline.com/calculator.asmx?wsdl",divide1,new SoapActionCallback("http://tempuri.org/Divide"));
return divideResponse;
}
public void MySoapClient() {
this.setInterceptors(new ClientInterceptor[] { new LoggingVonfig() });
}
}
. . .
This is my client class
. . .
package com.example.Soap;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
#Configuration
public class CalculatorConfig {
#Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
// jaxb2Marshaller.setPackagesToScan("com.example.Soap.com.example.Soap");
jaxb2Marshaller.setContextPath("com.example.Soap.com.example.Soap"); // this will serilaize and unserialize it
return jaxb2Marshaller;
}
#Bean
public CalculatorClient calculatorClient(Jaxb2Marshaller jaxb2Marshaller){
WebServiceTemplate wsTemplate = new WebServiceTemplate();
CalculatorClient calculatorClient = new CalculatorClient();
calculatorClient.setDefaultUri("http://www.dneonline.com");
calculatorClient.setMarshaller(jaxb2Marshaller);
calculatorClient.setUnmarshaller(jaxb2Marshaller);
return calculatorClient;
}
}
. . .
configuration file
. . .
package com.example.Soap;
import com.example.Soap.com.example.Soap.Add;
import com.example.Soap.com.example.Soap.AddResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication
#RestController
public class SoapApplication {
#Autowired
private CalculatorClient calculatorClient;
#PostMapping(value = "/add")
public com.example.Soap.com.example.Soap.AddResponse addelements(#RequestBody com.example.Soap.com.example.Soap.Add add){
return calculatorClient.getaddition(add);
}
#PostMapping(value = "/subtract")
public com.example.Soap.com.example.Soap.SubtractResponse addelements(#RequestBody com.example.Soap.com.example.Soap.Subtract subreq){
return calculatorClient.getSubtract(subreq);
}
#PostMapping(value = "/multiply")
public com.example.Soap.com.example.Soap.MultiplyResponse addelements(#RequestBody com.example.Soap.com.example.Soap.Multiply multiply){
return calculatorClient.getMultiply(multiply);
}
#PostMapping(value = "/divide")
public com.example.Soap.com.example.Soap.DivideResponse addelements(#RequestBody com.example.Soap.com.example.Soap.Divide divide){
return calculatorClient.getDivide(divide);
}
public static void main(String[] args) {
SpringApplication.run(SoapApplication.class, args);
}
}
. . .
These are my classes but still, I can't able to log all requests and responses in my console. I'm not getting where I have done wrong.
I implemented Client configuration too.
An easiest way is adding attribute into your security config (securityPolicy.xml):
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true">
No additional settings inside application.properties required.
Check that link to understanding security policy file.