Announcement

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

    Operation type viewFile, requiresAuthentication and dataURL

    1. SmartClient Version: v9.1p_2014-10-15/Pro Deployment (built 2014-10-15)
    2. Chrome

    Hi,

    I have a datasource 'product' that have an imageFile field and requires authentication for everything but fetch

    Code:
    <DataSource 
    	ID="product" 
    	tableName="product" 
    	serverType="sql"
    	xmlns:fmt="WEB-INF/"
        requiresAuthentication="true"
        dataURL="auth/authenticatedOperations"
    	>
    ...
    ...
    ...
    		<field name="img" type="imageFile" required="false" iconField="true" maxFileSize="51200">
    			<title><fmt:message key="picture"/></title>
            </field>
    ...
    ...
    ...
    	<operationBindings>
            <operationBinding 
                operationType="fetch"
                requiresAuthentication="false"
                dataURL="auth/nonAuthenticatedOperations"
    		/>
    	    <operationBinding operationType="update" requiresRole="admin"/>
    	    <operationBinding operationType="remove" requiresRole="admin"/>
    	    <operationBinding operationType="add" requiresRole="admin"/>
    	</operationBindings>
    The records are shown in a TileGrid. Each record data is shown OK in the Tile but the image, having the special "second call" to the web server in the SRC attribute, like:

    Code:
    http://127.0.0.1/[module]/images/auth/nonAuthenticatedOperations/babyBottle.png?isc_rpc=1&isc_v=v9.1p_2014-10-15&isc_tnum=3&_tran...........
    The servlet 'nonAuthenticatedOperations' is like below, I cannot trap the "viewFile" operation in it but I can identify the fetch operation.

    What the response in the servlet must have in order for the tile to show the image?
    From where is coming the "images" in the string?,
    Where can I modify that?

    Code:
        public void doPost(HttpServletRequest request, HttpServletResponse response)
        {
            RPCManager rpc;
    
            try
            {
                rpc = new RPCManager(request, response);
                
                for (Iterator i = rpc.getRequests().iterator(); i.hasNext();)
                {
                    Object req = i.next();
                    if (req instanceof RPCRequest)
                    {
                        throw new Exception("Only DSRequests expected");
                    } else
                    {
                        DSRequest dsRequest = (DSRequest) req;
    
                            DSResponse resp = dsRequest.execute();
                            rpc.send(dsRequest, resp);
                    }
                }
            } catch (Exception e)
            {
                LoggerHelper.logError("", "doPost", logger, e.getMessage(),
                        e.getStackTrace());
                return;
            }
    
        }

    The servlet is declared like

    Code:
    	<servlet>
    		<servlet-name>NonAuthenticatedOperations</servlet-name>
    		<servlet-class>path.to.server.class.NonAuthenticatedOperations</servlet-class>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>NonAuthenticatedOperations</servlet-name>
    		<url-pattern>/auth/nonAuthenticatedOperations</url-pattern>
    	</servlet-mapping>
    Thanks in advance,

    #2
    Just add an additional <operationBinding> with operationType="viewFile" and requiresAuthentication="false"

    Comment


      #3
      ...

      Adding this lines to the DataSource generates the same SRC for the image in the tile:
      Code:
              <operationBinding 
                  operationType="viewFile"
                  requiresAuthentication="false"
                  dataURL="auth/nonAuthenticatedOperations"
      		/>
      And the tile show
      Code:
      <img src="http://127.0.0.1/[module]/images/auth/nonAuthenticatedOperations/babyBottle.png?isc_rpc=1&isc_v=v9.1p_2014-10-15&isc_tnum=3&_tran...........">
      No image is shown and I cannot identify the viewFile request in the servlet.

      Any other suggestion?

      Thanks

      Comment


        #4
        ...

        And adding (with no dataURL attribute)

        Code:
                <operationBinding 
                    operationType="viewFile"
                    requiresAuthentication="false"
        		/>
        The tile show
        Code:
        <img src="http://127.0.0.1/[module]/images/auth/authenticatedOperations/babyBottle.png?isc_rpc=1&isc_v=v9.1p_2014-10-15&isc_tnum=3&_tran...........">
        No image is shown, the difference is what DataURL is used: the one for the DataSource (authenticatedOperations) or the one eplicitly set in the operation binding (nonAuthenticatedOperations).

        Any other suggestion?

        Thanks

        Comment


          #5
          Like the default IDACall Servlet, your custom Servlet should be registered for all URLs underneath its path (so auth/nonAuthenticatedOperations*).

          Comment


            #6
            ...

            In web.xml I made several tests without success. Having these maps
            1
            Code:
            	<servlet-mapping>
            		<servlet-name>NonAuthenticatedOperations</servlet-name>
            		<url-pattern>/auth/nonAuthenticatedOperations/*</url-pattern>
            	</servlet-mapping>
            2
            Code:
            	<servlet-mapping>
            		<servlet-name>NonAuthenticatedOperations</servlet-name>
            		<url-pattern>/auth/nonAuthenticatedOperations</url-pattern>
            	</servlet-mapping>
            3
            Code:
            	<servlet-mapping>
            		<servlet-name>IDACall</servlet-name>
            		<url-pattern>/auth/nonAuthenticatedOperations/*</url-pattern>
            	</servlet-mapping>
            4
            Code:
            	<servlet-mapping>
            		<servlet-name>IDACall</servlet-name>
            		<url-pattern>/auth/nonAuthenticatedOperations</url-pattern>
            	</servlet-mapping>
            We cannot use 1-3, 2-4 at the same time. The cases: 1 only, 1 + 4, 2 only, 2+3, 3 only, 4 only; leads us to the same: "images" is in the middle of the image SRC, after the [module] and before the call (with parameters) to the servlet.

            Comment


              #7
              ...

              Something to take into consideration is the "images" in the middle of the path, I saw in the ISC_Grid.js, related to the DetailViewer lines like:
              Code:
              output_value : function (fieldNum, field, valueList) {
              ...
                      if (field.type == "image") {
              ...
                          var src = this.getCellValue(record, field), prefix =
                              field.imageURLPrefix || field.baseURL || field.imgDir;
              ...
                              formattedValue = this.imgHTML(src, dimensions.width, dimensions.height, null,
                                  field.extraStuff, prefix, field.activeAreaHTML);
              ...
              It looks like the DataViewerField contains something in imageURLPrefix or baseURL or imgDir. Setting those attributes to "" doesn't help either.

              Comment


                #8
                Summary

                In a different scenario (but at the end is the same) I made a second test and got the same result.

                Having:
                *** a ListGrid that shows the records properly with the standard SmartClient layout for a FileItem column (view icon + download icon + name).
                *** a DynamicForm that shows the selected record in the grid. This form has a CanvasItem with an Img widget 'thumbnail'. When the record is selected, the Img source is set:
                Code:
                String src = ds.getFileURL(record, getName());
                thumbnail.setSrc(src);
                I found several things that must happen for this to work, but still cannot identify what to do to remove the "images" in the middle of the path

                Summary
                1. The objective is to have authentication=true and dataURL='auth/SERVLET_A' in any given DataSource XML (DS) with at least one field of type "imageFile"
                2. Some operations in the DS will be relaxed for authentication (false), for example, fetch with dataURL='auth/SERVLET_B'
                3. SERVLET_B is mapped in the web.xml as "/auth/SERVLET_B/*"

                First required condition in SERVLET_B java code (this is important):
                The operation doGet must be implemented for the viewFile to complete successfuly. How to know this is working? Copy the output SRC in the TileGrid or the Img widget, remove the "images" word, and copy in a new browser tab, it will show the picture only if doGet exists.

                SERVLET_B
                Code:
                public void doPost(HttpServletRequest request, HttpServletResponse response)
                {
                     Do something with the request
                }
                
                public void doGet(HttpServletRequest request, HttpServletResponse response)
                {
                     Do something with the request OR
                    simply call doPost(request, response)
                }
                Current situation:
                1. By default the DataSource.getFileURL() always returns "auth/SERVLET_B/IMAGE_FILE_NAME.EXT?several parameters". This is OK. This must be happening with the TileGrid too.

                2. When Img.setSrc(DataSource.getFileURL()) is called, the SRC field is prefixed with WEB_SITE_URL + "images". This is what must happen as it is said in "com.smartgwt.client.docs.SCImgURL" : "... any relative path is assumed to be relative to the "application image directory" (appImgDir) ...". This is happening and must be happening with the TileGrid too.

                Where the problem is not?:
                If the SERVLET_B is mapped as "/auth/SERVLET_B/*" or "/auth/SERVLET_B" the DataSource.getFileURL() will return the same. This is OK.

                Problem:
                How can we get rid of the "images" without explicitly saying Page.setAppImgDir("")?, because this call will impact any other request for icons in the other different widgets.
                If we explicity say dataURL='WEB_SITE_URL/auth/SERVLET_B' in the DataSource XML, it will work because the path is not relative, but this is not acceptable as a solution.

                Thanks

                Comment


                  #9
                  ...

                  I forgot to mention that IDACall must be mapped to SERVLET_B with/without the asterisk '*' depending in the other
                  Code:
                  	<servlet-mapping>
                  		<servlet-name>MY_SERVLET_B</servlet-name>
                  		<url-pattern>/auth/SERVLET_B</url-pattern>
                  	</servlet-mapping>
                      <servlet-mapping>
                          <servlet-name>IDACall</servlet-name>
                          <url-pattern>/auth/SERVLET_B/*</url-pattern>
                      </servlet-mapping>
                  A simplest solution for the viewFile operation to work is (and there is no custom servlet involved)
                  1.- Map IDACall to something, for instance
                  Code:
                      <servlet-mapping>
                          <servlet-name>IDACall</servlet-name>
                          <url-pattern>/auth/IDACall/*</url-pattern>
                      </servlet-mapping>
                  2.- Set dataURL to a non-relative path in the viewFile operation binding, pointing to the above map
                  Code:
                      dataURL='WEB_SITE_URL/auth/IDACall'
                  Having this, the picture is shown. What I miss is a property in the client DataSource that say the dataURL have to be used as non-relative.

                  This happens if we do not use dataURL at all, in this case the servlet path used by default is [module]/sc/IDACall (the default servlet for all requests) and the SmartGWT/Client libraries deal with this as a non-relative dataURL path, then the SRC ends up like 'WEB_SITE_URL/[module]/sc/IDACall/IMAGE_FILE_NAME.EXT?parameters'.

                  Still I have the same question, how to get rid of the "images" string when the dataURL is relative?

                  Any suggestion?

                  Thanks,

                  Comment


                    #10
                    Looks like you tried every web.xml registration you could think of, except for what we actually said to use :) That was:

                    Originally posted by Isomorphic View Post
                    Like the default IDACall Servlet, your custom Servlet should be registered for all URLs underneath its path (so auth/nonAuthenticatedOperations*).
                    "images" is present because it's the default for "appImgDir" (see docs on Page class for how to configure system-wide default base URLs). It probably should not be used in this case, we'll take a look.

                    Comment


                      #11
                      ...

                      No. I tested your case without success.

                      The mappings I'm using are
                      Code:
                      	<servlet>
                      		<servlet-name>NonAuthenticatedOperations</servlet-name>
                      		<servlet-class>path.to.server.class.NonAuthenticatedOperations</servlet-class>
                      	</servlet>
                      	<servlet-mapping>
                      		<servlet-name>NonAuthenticatedOperations</servlet-name>
                      		<url-pattern>/auth/nonAuthenticatedOperations</url-pattern>
                      	</servlet-mapping>
                          <servlet-mapping>
                              <servlet-name>IDACall</servlet-name>
                              <url-pattern>/auth/nonAuthenticatedOperations/*</url-pattern>
                          </servlet-mapping>
                      It is working only if NonAuthenticatedOperations class implements doGet and if dataURL is a non-relative path to "auth/nonAuthenticatedOperations". In any other case the appImgDir will be there, and the effect is that the image is not showing.

                      About the appImgDir, it is clear what "images" is. Thanks anyway for clarify it.
                      This is what must happen as it is said in "com.smartgwt.client.docs.SCImgURL" : "... any relative path is assumed to be relative to the "application image directory" (appImgDir) ...".
                      What still is not answered is
                      how to get rid of the "images" string when the dataURL is a relative path?

                      Comment


                        #12
                        No, in your web.xml, you included a slash where we did not.

                        As far as needing to provide a doGet(), this is not necessary if you simply subclass IDACall. We're not sure what implementation approach you took, but doing anything other than subclassing IDACall in this circumstance would not be supported. The request being sent is intended for the IDACall servlet and it's format is not documented such that a custom-coded servlet could process it.

                        Finally, again, we're looking into the "images" path issue, which is actually the same issue as requiring a non-relative dataURL. That appears to be the only actual issue reported in this thread.

                        Comment


                          #13
                          ...

                          That appears to be the only actual issue reported in this thread
                          Completely true.

                          It took several tests with dataURL, setSrc, and the web.xml servlet declaration in order to realize that: no matter the custom servlet, if it is well defined, the problem is that appImgDir will be there and the image will not be shown in a TileGrid with dataURL property set in the DS.xml

                          Comment


                            #14
                            ...

                            Hi,

                            Is there any solution?

                            Thanks

                            Comment


                              #15
                              Hi Omar,

                              is display working if you just call the image URL in the browser?
                              Is the URL the same you can see in the Firefox F12 Tools's Network tab when showing your TileGrid?

                              Best regards,
                              Blama

                              Comment

                              Working...
                              X