Search code examples
javaspringrestcurlcxf

Apache CXF Spring rest service POST request returns "msg" : "Stream closed"


I work with an Apache Cxf, Spring Jax-rs service and I have the following service definition and the implementations provided,

THE DEFINITION

    @POST
    @Path("/generateAddress")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces({MediaType.APPLICATION_JSON})
    WalletInfo generateAddress(final String walletName, String currencyName);

THE IMPLEMENTATIONS

public synchronized WalletInfo generateAddress(final String walletName, String currencyName) {

        WalletInfo walletInfo = IWalletInfoDao.getWalletInfoWithWalletNameAndCurrency(walletName, currencyName);
        return walletInfo;
}

When I do the POST request with the cURL like curl -H "Content-Type: application/json" -X POST -d '{"walletName":"Icecream5500","currencyName":"Bitcoin"}' http://localhost:8080/api/rest/wallet/generateAddress

I get the JSON response back,

{
  "msg" : "Stream closed",
  "date" : "2017-08-28T09:22:027Z"
}

I'm pretty sure that the generateAddress method works fine. What is
the issue here and particularly, when you would get the message Stream closed in the Spring Apache Cxf project while doing the POST requests? Obviously, I can provide more info if required. The server log is normal and I see nothing unusual.


Solution

  • The POST body doesn't match with the parameters of the method and this created the issue in the first place. I have solved the problem in the following options.

    I created a new class

    public class CreateWalletWithNameAndCurrency {
    
        String walletName;
    
        String currencyName;
    
        public CreateWalletWithNameAndCurrency(String walletName, String currencyName) {
            this.walletName = walletName;
            this.currencyName = currencyName;
        }
    
        public CreateWalletWithNameAndCurrency() {
        }
    
        public String getWalletName() {
            return walletName;
        }
    
        public String getCurrencyName() {
            return currencyName;
        }
    
        public void setCurrencyName(String currencyName) {
            this.currencyName = currencyName;
        }
    
        public void setWalletName(String walletName) {
            this.walletName = walletName;
        }
    }
    

    I changed the definition of the POST request like this,

    @POST
    @Path("generateAddress")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces({MediaType.APPLICATION_JSON})
    WalletInfo generateAddress(CreateWalletWithNameAndCurrency createWalletWithNameAndCurrency);
    

    The implementation is provided below,

    public synchronized WalletInfo generateAddress(CreateWalletWithNameAndCurrency createWalletWithNameAndCurrency) {
    
            String walletName = createWalletWithNameAndCurrency.getWalletName();
    
            String currencyName = createWalletWithNameAndCurrency.getCurrencyName();
    
            WalletInfo walletInfo = iWalletInfoDao.getWalletInfoWithWalletNameAndCurrency(walletName, currencyName);
    
    
        // some more code 
    }
    

    Finally, I can do the POST request like this,

    curl -H "Content-Type: application/json" -X POST -d '{"walletName":"Copenhangen","currencyName":"Bitcoin"}' http://localhost:8080/rest/wallet/generateAddress