Announcement

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

    RestDataSource server side code ?!

    Hi,

    i'm new to smart gwt lgpl version. I try to create a simple combobox which loads asynchronous the data via restdatasource (which gets the records from a database via jdbc).

    My problem is: i don't know how to start on server-side ... ?!

    Is there any example?


    Thanks!

    #2
    Nope. That's up to your choice of server. If you are using the SmartClient Server Framework you don't have to use a RestDataSource at all and you can connect right up to your database without code. Sure saves a ton of time.

    If you cannot swing the license you will need to implement your server rest data service to match the RestDataSource docs for data transfer. How you do that is up to you.

    Comment


      #3
      you mean via GWT-RPC?

      Comment


        #4
        That is doable but see the FAQ for reasons not to choose GWT-RPC. You should also reason the quick start guide if you have not already done so.

        Comment


          #5
          Ok, i will read it again. What's the alternative to GWT RPC? Remember i do not use the SmartGWT EE Version...

          Comment


            #6
            If your server is Java then you can use a library like Gson to create a JSON string to return.

            I tried this out for a bit and it's not too difficult. I basically produce a list of objects and then use Gson to serialize/deserialize it. One sticky point was the date format, which needs to be set as below. I'm sure there are probably a few more gotchas. Aside from the code below, you also need to implement add/update/remove. Below is a sample of a fetch.

            Code:
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
            				.create();
            
            ...
            
            List<?> list = processRequest(req);
            String string = gson.toJson(new ResponseWrapper(new Response(list)));

            These are the wrapper classes to produce something which looks right to SmartGWT RestDataSource.

            Code:
            import java.util.Arrays;
            import java.util.List;
            
            public class Response {
            
            	public int status;
            	public int startRow;
            	public int endRow;
            	public int totalRows;
            	public List<Object> data;
            
            	public Response(Object object) {
            		List<Object> list;
            		if (object instanceof List)
            			list = (List<Object>) object;
            		else
            			list = (Arrays.asList(new Object[] { object }));
            
            		startRow = 0;
            		endRow = list.size();
            		totalRows = list.size();
            		data = list;
            	}
            
            }

            Code:
            public class ResponseWrapper {
            
            	private Response response;
            
            	public ResponseWrapper(Response response) {
            		this.setResponse(response);
            	}
            
            	public void setResponse(Response response) {
            		this.response = response;
            	}
            
            	public Response getResponse() {
            		return response;
            	}
            
            }

            Comment


              #7
              May as well post the client side definition too (replace result.get("name") with your datasource name). Likewise, you need to configure your server to handle whatever URL you point it at.

              Code:
              				RestDataSource dataSource = new RestDataSource();
              
              				dataSource.setID(result.get("name"));
              
              				String baseUrl = Window.Location.getProtocol() + "//"
              						+ Window.Location.getHost();
              
              				String fetchURL = ((baseUrl + "/api/fetch/" + result
              						.get("name")));
              				String addURL = (baseUrl + "/api/add/" + result.get("name"));
              				String updateURL = (baseUrl + "/api/update/" + result
              						.get("name"));
              				String removeURL = (baseUrl + "/api/remove/" + result
              						.get("name"));
              
              				OperationBinding remove = new OperationBinding(
              						DSOperationType.REMOVE, removeURL);
              				OperationBinding update = new OperationBinding(
              						DSOperationType.UPDATE, updateURL);
              				OperationBinding add = new OperationBinding(
              						DSOperationType.ADD, addURL);
              				OperationBinding fetch = new OperationBinding(
              						DSOperationType.FETCH, fetchURL);
              
              				fetch.setDataFormat(DSDataFormat.JSON);
              				add.setDataFormat(DSDataFormat.JSON);
              				update.setDataFormat(DSDataFormat.JSON);
              				remove.setDataFormat(DSDataFormat.JSON);
              				dataSource.setOperationBindings(fetch, add, update, remove);

              Comment


                #8
                Thanks for your reply... but how do i "deploy" the rest service on server side?

                Comment


                  #9
                  atomatom, thank you ! You are the first post I've every found that explains this! I've serialized my objects into JSON but was stuck from there.

                  One question -- when you say, "configure your server to handle whatever URL you point it at", what do you mean by that? I can certainly get the URL of the server, but the URL has always been my sticking point -- I've got the JSON string, I can create the data source, but I'm still unsure what to enter as the "URL".

                  Thanks in advance!

                  Comment


                    #10
                    Yes, that's one of my problems too...

                    Comment


                      #11
                      Hi deejay,
                      When you set RestDataSource.setDataURL("/something.service") Sgwt framework will trigger http request with url http://yourhost:port/module/something.service. This means that you will need servlet on server side (configured in web.xml) witch will respond. Instead of servlets I am using spring mvc framework (with httpRequestHandler interface)
                      my httpDispatcher.xml example file:
                      Code:
                      	<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                      		<property name="mappings">
                      			<map>
                      				<entry key="/**/DateTimeTest.Service" value-ref="dateTimeTestBean"/>
                      			</map>
                      		</property>
                      	</bean>
                      	<bean id="dateTimeTestBean" class="pl.com.intuicja.server.DateTimeTestBean">
                      		<property name="dateTimeTestDao" ref="dateTimeTestDao"/>
                      	</bean>
                      and RestDataSource client side example
                      Code:
                      public class DateTimeDS extends RestDataSource {
                      	private static DateTimeDS ds;
                      	public static DateTimeDS getInstance(){
                      		if (ds == null){
                      			ds = new DateTimeDS("DateTimeDS");
                      		}
                      		return ds;
                      		
                      	}
                      	public DateTimeDS(String id) {
                      		setID(id);
                      		setDataFormat(DSDataFormat.XML);
                      		setDataProtocol(DSProtocol.POSTXML);
                      		setDataURL(GWT.getModuleBaseURL() + "DateTimeTest.Service");
                      		OperationBinding addOB = new OperationBinding();
                      		addOB.setOperationType(DSOperationType.ADD);
                      		OperationBinding updateOB = new OperationBinding();
                      		updateOB.setOperationType(DSOperationType.UPDATE);
                      		OperationBinding removeOB= new OperationBinding();
                      		removeOB.setOperationType(DSOperationType.REMOVE);
                      		OperationBinding fetchOB= new OperationBinding();
                      		fetchOB.setOperationType(DSOperationType.FETCH);
                      		setOperationBindings(fetchOB,addOB,removeOB,updateOB);
                      		DataSourceIntegerField dsifIdCzasu = new DataSourceIntegerField("idCzasu");
                      		dsifIdCzasu.setPrimaryKey(true);
                      		DataSourceDateTimeField dsdtfDataOd = new DataSourceDateTimeField("dataOd");
                      		setFields(dsifIdCzasu, dsdtfDataOd);
                      		
                      	}
                      
                      }
                      server side class (I am using xml request and response, jdom and jaxen for xml parsing) :

                      Code:
                      public class DateTimeTestBean implements HttpRequestHandler {
                      	private DateTimeTestDao dateTimeTestDao;
                      	@Override
                      	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
                      			throws ServletException, IOException {
                      		request.setCharacterEncoding("UTF-8");
                      		response.setCharacterEncoding("UTF-8");
                      		XPath xpath; 
                      		XMLOutputter wyjscie = new XMLOutputter(Format.getPrettyFormat());
                      		SAXBuilder saxBuilder = new SAXBuilder();
                      		try {
                      			Document reqDoc = saxBuilder.build(request.getReader());
                      			wyjscie.output(reqDoc, System.out);
                      			Element rootEl = reqDoc.getRootElement();
                      			String operationType = rootEl.getChildText("operationType");
                      			if (operationType.equalsIgnoreCase("fetch")){
                      				PaczkaCzasy paczkaCzasy = dateTimeTestDao.fetchCzasy(reqDoc);
                      				Document responseDoc = genXmlResponse(paczkaCzasy);
                      				wyjscie.output(responseDoc, response.getWriter());
                      				wyjscie.output(responseDoc, System.out);
                      			}
                      			if (operationType.equalsIgnoreCase("add")){
                      				PaczkaCzasy paczkaCzasy = dateTimeTestDao.addCzasy(reqDoc);
                      				Document responseDoc = genXmlResponse(paczkaCzasy);
                      				wyjscie.output(responseDoc, response.getWriter());
                      				wyjscie.output(responseDoc, System.out);
                      			}
                      		} catch (Exception e) {
                      			// TODO Auto-generated catch block
                      			e.printStackTrace();
                      		}
                      	}
                      	public void setDateTimeTestDao(DateTimeTestDao dateTimeTestDao) {
                      		this.dateTimeTestDao = dateTimeTestDao;
                      	}
                      	public DateTimeTestDao getDateTimeTestDao() {
                      		return dateTimeTestDao;
                      	}
                      	public Document genXmlResponse(PaczkaCzasy paczkaCzasy){
                      		Document responsedoc = new Document();
                      		Element rootElresp = new Element("response");
                      		responsedoc.setRootElement(rootElresp);
                      		Element elStatus = new Element("status");
                      		elStatus.setText("0");
                      		Element elStartRow = new Element("startRow");
                      		elStartRow.setText(String.valueOf(paczkaCzasy.getStartRow()));
                      		Element elEndRow = new Element("endRow");
                      		elEndRow.setText(String.valueOf(paczkaCzasy.getEndRow()));
                      		Element elTotalRows= new Element("totalRows");
                      		elTotalRows.setText(String.valueOf(paczkaCzasy.getTotalRows()));
                      		
                      		Element elData = new Element("data");
                      		rootElresp.addContent(elStatus);
                      		rootElresp.addContent(elStartRow);
                      		rootElresp.addContent(elEndRow);
                      		rootElresp.addContent(elTotalRows);
                      		rootElresp.addContent(elData);
                      		for (Czas czas : paczkaCzasy.getDane()){
                      			Element elRecord = new Element("record");
                      			elData.addContent(elRecord);
                      			Element elIdCzasu = new Element("idCzasu");
                      			if (czas.getDataOd() != null){
                      				Element elDataOd = new Element("dataOd");
                      				String dataOd = sdf.format(czas.getDataOd());
                      
                      				elDataOd.setText(dataOd);
                      				elRecord.addContent(elDataOd);
                      			}
                      
                      			}
                      		
                      		
                      		return responsedoc;
                      	}
                      
                      }
                      I hope it will help you

                      Comment


                        #12
                        Thank you very much..

                        Is there an example without spring mvc but with default gwt?

                        Comment


                          #13
                          Originally posted by deejay
                          but with default gwt?
                          what do you mean by that ?

                          Comment


                            #14
                            I meant how to setup the gwt.xml with out spring mvc.

                            Comment


                              #15
                              "gwt.xml" you mean by that you are intend to use gwt-rpc ?
                              If so, I do not know if you are aware that it is not suported by Smartgwt framework with lgpl license. There is user-extension project for that, but it is not ready for production development with my opinion

                              Comment

                              Working...
                              X