Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    RestDataSource GET and POSTMESSAGE

    The question is, I have a RestDataSource. I have used these before, and it all works well for me. I created my web-services to specifically work with RestDataSources with a SmartGWT web-app.

    However, for this RestDataSource, the only thing I changed is that in the init() method, when I set the bindings, for the fetch binding, using the setHttpMethod GET, I want to send back an object with some information in it, so I set the data protocol to POSTMESSAGE.

    However, I keep getting the Error 415 UNSUPPORTED_MEDIA_TYPE from my Spring MVC Controller (which is documented below).

    The Controller was unit tested, and seems to work just fine, but the call from the datasource seems to be missing something.

    I should also explain that the data being passed as JSON looks like:
    String jsonData = "{\"userId\":3, \"ddUserId\":301010651, \"customerCode\":\"QA\", \"customerId\":8}";
    and using the JacksonMessageConverter in Spring, this json string is correctly translated into the SearchInvoiceDTO, so that should not be an issue.

    I have tried to provide as much information as I can. I have provided the RPC Request and DS Request as shown in the SmartGWT Dev Console.

    If anymore information is needed, please let me know.

    1. SmartGWT 4.0
    SmartClient Version: v9.0_2013-07-03/LGPL Development Only (built 2013-07-03)

    2. FireFox 23.0.1

    3. Log:
    Code:
    09:55:50.808 [ERROR] [RevenueManager] 09:55:50.808:XRP5:WARN:RPCManager:Server returned TRANSPORT_ERROR with no error message. - response: {status: -90,
    data: Obj,
    httpResponseCode: 415,
    transactionNum: 0,
    clientContext: Obj,
    httpHeaders: Obj,
    context: Obj,
    queueStatus: -1,
    startRow: 0,
    endRow: 0,
    totalRows: 0}
    
    com.smartgwt.client.core.JsObject$SGWT_WARN: 09:55:50.808:XRP5:WARN:RPCManager:Server returned TRANSPORT_ERROR with no error message. - response: {status: -90,
    data: Obj,
    httpResponseCode: 415,
    transactionNum: 0,
    clientContext: Obj,
    httpHeaders: Obj,
    context: Obj,
    queueStatus: -1,
    startRow: 0,
    endRow: 0,
    totalRows: 0}
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
        at java.lang.Thread.run(Thread.java:662)
    4. RPC Request
    Code:
    {
        "actionURL":"rest/invoices/searchAndCount", 
        "showPrompt":true, 
        "prompt":"Finding Records that match your criteria...", 
        "transport":"xmlHttpRequest", 
        "useSimpleHttp":true, 
        "promptStyle":"cursor", 
        "httpMethod":"GET", 
        "contentType":"application/json", 
        "sendNoQueue":true, 
        "bypassCache":true, 
        "data":"{\r    \"userId\":3, \r    \"ddUserId\":301010651, \r    \"customerCode\":\"QA\", \r    \"customerId\":8\r}"
    }
    DS Request
    Code:
    {
        dataSource:"restInvoiceDS", 
        operationType:"fetch", 
        componentId:"isc_ListGrid_0", 
        data:"{\r    \"userId\":3, \r    \"ddUserId\":301010651, \r    \"customerCode\":\"QA\", \r    \"customerId\":8\r}", 
        startRow:0, 
        endRow:75, 
        textMatchStyle:"substring", 
        resultSet:[ResultSet ID:isc_ResultSet_0 (created by: isc_ListGrid_0)], 
        callback:{
            caller:[ResultSet ID:isc_ResultSet_0 (created by: isc_ListGrid_0)], 
            methodName:"fetchRemoteDataReply"
        }, 
        willHandleError:true, 
        showPrompt:true, 
        prompt:"Finding Records that match your criteria...", 
        requestId:"restInvoiceDS$6270", 
        clientContext:{
            requestIndex:1
        }, 
        fallbackToEval:false, 
        lastClientEventThreadCode:"MUP4[E]", 
        httpMethod:"GET", 
        contentType:"application/json", 
        bypassCache:true, 
        actionURL:"rest/invoices/searchAndCount"
    }
    I have a RestDataSource:
    Code:
    public class InvoiceDataSource extends RestDataSource
    {
        private static InvoiceDataSource instance = null;
    
        public static InvoiceDataSource getInstance()
        {
            if (instance == null)
            {
                instance = new InvoiceDataSource("restInvoiceDS");
            }
            return instance;
        }
    
        private InvoiceDataSource(String id)
        {
            setID(id);
            setClientOnly(false);
    
            // set up FETCH to use GET requests
            OperationBinding fetch = new OperationBinding();
            fetch.setOperationType(DSOperationType.FETCH);
            fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
            fetch.setDataFormat(DSDataFormat.JSON);
            // ===========================================
            DSRequest fetchProps = new DSRequest();
            fetchProps.setHttpMethod("GET");
            fetchProps.setContentType("application/json");
            fetch.setRequestProperties(fetchProps);
    
            // set up ADD to use POST requests
            OperationBinding add = new OperationBinding();
            add.setOperationType(DSOperationType.ADD);
            add.setDataProtocol(DSProtocol.POSTMESSAGE);
            // ===========================================
            DSRequest addProps = new DSRequest();
            addProps.setHttpMethod("POST");
            add.setRequestProperties(addProps);
    
            // set up UPDATE to use PUT
            OperationBinding update = new OperationBinding();
            update.setOperationType(DSOperationType.UPDATE);
            update.setDataProtocol(DSProtocol.POSTMESSAGE);
            // ===========================================
            DSRequest updateProps = new DSRequest();
            updateProps.setHttpMethod("PUT");
            // updateProps.setContentType("application/json");
            update.setRequestProperties(updateProps);
    
            // set up REMOVE to use DELETE
            OperationBinding remove = new OperationBinding();
            remove.setOperationType(DSOperationType.REMOVE);
            DSRequest removeProps = new DSRequest();
            removeProps.setHttpMethod("DELETE");
            remove.setRequestProperties(removeProps);
    
            // apply all the operational bindings
            setOperationBindings(fetch, add, update, remove);
    
            init();
        }
    
        private DataSourceIntegerField invoiceNumberIdField;
        private DataSourceIntegerField invoiceNumberField;
        private DataSourceFloatField invoiceAmountField;
        private DataSourceTextField invoiceCurrencyField;
        private DataSourceIntegerField invoiceWaitingField;
        private DataSourceTextField invoiceAccounts;
        private DataSourceTextField invoicePeriodField;
        private DataSourceTextField invoiceTimingField;
    
        protected void init()
        {
            setDataFormat(DSDataFormat.JSON);
            setJsonRecordXPath("/");
    
            RPCManager.setAllowCrossDomainCalls(true);
    
            invoiceNumberIdField =
                new DataSourceIntegerField(InvoiceConstants.INVOICE_NUMBER_ID, InvoiceConstants.TITLE_INVOICE_NUMBER_ID);
            invoiceNumberIdField.setPrimaryKey(true);
            invoiceNumberIdField.setCanEdit(false);
    
            invoiceNumberField =
                new DataSourceIntegerField(InvoiceConstants.INVOICE_NUMBER, InvoiceConstants.TITLE_INVOICE_NUMBER);
            invoiceNumberField.setCanEdit(false);
    
            invoiceAmountField =
                new DataSourceFloatField(InvoiceConstants.INVOICE_AMOUNT, InvoiceConstants.TITLE_INVOICE_AMOUNT);
    
            invoiceCurrencyField =
                new DataSourceTextField(InvoiceConstants.INVOICE_CURRENCY, InvoiceConstants.TITLE_INVOICE_CURRENCY);
    
            invoiceWaitingField =
                new DataSourceIntegerField(InvoiceConstants.INVOICE_WAITING, InvoiceConstants.TITLE_INVOICE_WAITING);
    
            invoiceAccounts = new DataSourceTextField(InvoiceConstants.INVOICE_ACCOUNTS, InvoiceConstants.INVOICE_ACCOUNTS);
    
            invoicePeriodField =
                new DataSourceTextField(InvoiceConstants.INVOICE_PERIOD, InvoiceConstants.TITLE_INVOICE_PERIOD);
    
            invoiceTimingField =
                new DataSourceTextField(InvoiceConstants.INVOICE_TIMING, InvoiceConstants.TITLE_INVOICE_TIMING);
    
            // ================================================================================================================
    
            setFields(invoiceNumberIdField, invoiceNumberField, invoiceAmountField, invoiceCurrencyField,
                invoiceWaitingField, invoiceAccounts, invoicePeriodField, invoiceTimingField);
    
            setFetchDataURL(getServiceRoot() + "/searchAndCount");
            setAddDataURL(getServiceRoot() + "/create");
            setUpdateDataURL(getServiceRoot() + "/update");
            setRemoveDataURL(getServiceRoot() + "/remove/{id}");
        }
    
        protected String getServiceRoot()
        {
            return "rest/invoices";
        }
    
        protected String getPrimaryKeyProperty()
        {
            return "invoiceNumberId";
        }
    
        @Override
        protected Object transformRequest(DSRequest dsRequest)
        {
            System.out.println("InvoiceDataSource: transformRequest: START");
            dsRequest.setContentType("application/json");
            JavaScriptObject jso = dsRequest.getData();
            String s1 = JSON.encode(jso);
            System.out.println("InvoiceDataSource: transformRequest: FINISH: s1=" + s1);
            return s1;
        }
    
        protected void transformResponse(DSResponse response, DSRequest request, Object data)
        {
            System.out.println("InvoiceDataSource: transformResponse: START");
            JavaScriptObject jso = (JavaScriptObject) data;
            String jsoText1 = JSON.encode(jso);
            System.out.println("InvoiceDataSource: transformResponse: START: jsoText1=" + jsoText1);
    
            String jsoText2 = JSON.encode(jso);
            System.out.println("InvoiceDataSource: transformResponse: FINISH: jsoText2=" + jsoText2);
    
            super.transformResponse(response, request, data);
            System.out.println("InvoiceDataSource: transformResponse: FINISH");
        }
    }
    Spring MVC Controller:
    Code:
    @RequestMapping(value = "/searchAndCount", method = RequestMethod.GET, produces = "application/json", headers =
        { "Accept=application/json", "Content-Type=application/json" }, consumes = "application/json")
        public @ResponseBody
        RequestResults<?> searchAndCount(@RequestBody SearchInvoiceDTO searchInvoiceDto)
        {    
    RequestResults<?> requestResults invoiceApprovalService.searchAndCount(searchInvoiceDto);
    
            return requestResults;
        }
    The Unit Test shows the controller works great:
    Code:
    MockHttpServletRequestBuilder requestBuilder =
                MockMvcRequestBuilders.get("/invoices/searchAndCount").contentType(MediaType.APPLICATION_JSON)
                .content(test);        this.mockMvc.perform(requestBuilder).andDo(print());
Working...
X