Friday, May 4, 2012

SOAP web service with Spring-WS 2.0 - Part 2

In Part 1, we have demonstrated how easy it is to create a service endpoint with Spring-WS 2.0. In Part 2, let's create a client program that will consume the service.

Step 1) create a Spring config file that defines a service template as "spring-ws-client.xml" and save it under source root folder:

<beans xmlns="http://www.springframework.org/schema/beans"
       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">

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="defaultUri" value="http://localhost:8080/SpringWSTest"/>
</bean>
</beans>

Step 2) create a static xml request message and save it as "TestRequest.xml" under "TestXmls" folder. Alternatively you can use you chosen xml parser to create the xml request in the code.

<tns:ProjectRequest
    xsi:schemaLocation="http://javaclue.blogger.com/ws-project ws-project.xsd"
    xmlns:tns="http://javaclue.blogger.com/ws-project"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <tns:Name>SpringWSTest</tns:Name>
</tns:ProjectRequest>

Step 3) create a client program and run it:

package javaclue.ws.client;

import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.ws.client.core.WebServiceTemplate;

public class ProjectSearchClient extends AbstractWebServiceClient {

    static String xmlFilePath = "TestXmls/TestRequest.xml";

    protected WebServiceTemplate webServiceTemplate;

    public void setDefaultUri(String defaultUri) {
        webServiceTemplate.setDefaultUri(defaultUri);
    }

    // send to the configured default URI
    public void simpleSendAndReceive(String message) {
        StreamSource source = new StreamSource(new StringReader(message));
        StreamResult result = new StreamResult(System.out);
        webServiceTemplate.sendSourceAndReceiveToResult(source, result);
    }

    protected String loadFromFile(String xmlFile) throws IOException {
        // load XML file to a string buffer
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream is = loader.getResourceAsStream(xmlFile);
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuffer fileData = new StringBuffer();
        char[] buf = new char[1024];
        int numRead = 0;
        while ((numRead = reader.read(buf)) != -1) {
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }
 

    // send to an explicit URI
    public void customSendAndReceive(String message) {
        String sURL = "http://localhost:8080/SpringWSTest/projectSearch.wsdl";

        StreamSource source = new StreamSource(new StringReader(message));
        Writer streamOut = new StringWriter();
        StreamResult result = new StreamResult(streamOut);
        webServiceTemplate.sendSourceAndReceiveToResult(sURL, source, result);
        System.out.println("\n########## Response:\n" + streamOut.toString());
    }

    public static void main(String[] args) {
        try {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] {"classpath*:/spring-ws-client.xml"});
            ProjectSearchClient client = new ProjectSearchClient();
            String message = client.loadFromFile(xmlFilePath);
            client.webServiceTemplate = (WebServiceTemplate)applicationContext.getBean("webServiceTemplate");
            client.customSendAndReceive(message);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Monday, January 2, 2012

Energy Veritas v5.1 / RC-10 Modification

Bought a pair of Energy Veritas v5.1 during the holidays and have been enjoying them since. The speakers are piano black and look beautiful. Best of all they sound very good and sound larger than their size.

However when I placed the speakers close to wall and they become a little too bass heavy and it muddies mid-range sometimes. I tried plugging the port with supplied foam but then there were too little bass. I measured the port it is about 2" in diameter and is about 4.6" long. Although I have not measured the woofer, I believe the port frequency is tuned too high for the cabinet. I figured lowering the port tuning frequency may improve the bass performance.

I went to Home-Depot and bought a two-feet 1.5" PVC pipe, and cut a  4.5" tube. The tube fits in the port opening but is loose and moves freely.

I wrapped the tube with some thin foam to make it fit snugly inside the port. (If you don't have thin foam, you could also try soft paper or cloth.)

I inserted the wrapped tube into the port and listened again and the muddiness is gone! The speakers are now feel more balanced. The bass is still very good for the size, and it seems go even lower than before the mod. And the bass is now tight and clean. The $3 investment on the PVC pipe and 20 minutes labor completed paid off.

Since RC-10 uses same drivers as Veritas v5.1 and the cabinet size is almost same. I believe the same modification can be applied to RC-10 as well.

This modification is easy to do and reversible. I figured if I don't like the sound after the modification, I could simply remove the tube from the port.