Hi,
  I've been coding an action which returns a streamed image based on
some image id. Quick and dirty, something like:

package org.chop.prjx.actions;

import java.io.*;
import java.slf4j.*;
import com.opensymphony.xwork2.ActionSupport;
import eu.medsea.mimeutil.MimeUtil;

public class ThumbnailAction extends ActionSupport {
  private static final Logger logger =
LoggerFactory.getLogger(ThumbnailAction.class);

  private String imageId;

  private BufferedInputStream imageStream;
  private String mimeType;
  private String fileName;
  private int bufSize = 1024;
  private String totSize="";


  public int getBuffSize() { return bufSize; }
  public void setBuffSize(int size) { bufSize = size; }

  public String getImageId() { return imageId; }
  public void setImageId(String id) { imageId = id; }


  public String execute() {
    logger.trace("(execute)");
    FileInputStream fis;
    String path = resolve(imageId);
    try {
      File f = new File(path);
      fileName = f.getName();
      totSize = Long.toString(f.length());
      mimeType =
MimeUtil.getMostSpecificMimeType(MimeUtil.getMimeTypes(f)).toString();
      fis = new FileInputStream(f);
      imageStream = new BufferedInputStream(fis, bufSize);
    } catch (FileNotFoundException e) {
      logger.error("(execute) Couldn't find: {}", path);
    }
    return SUCCESS;
  }

  public InputStream getInputStream() { return imageStream; }
  public String getMimeType() { return mimeType; }
  public String getFileName() { return fileName; }
  public String getLength() { return totSize; }

  public String resolve(final String id) {
    String retVal = "C:\\Java\\M\\Import\\" + id + ".mini.png";
    logger.debug("(resolve) id: {} --> path: {}", id, retVal);
    return retVal;
  }
}

My struts.xml file:
<struts>
  <constant name="struts.enable.DynamicMethodInvocation" value="false" />
  <constant name="struts.multipart.saveDir" value="/tmp" />
  <constant name="struts.url.includeParams" value="none" />

  <package name="admin" extends="struts-default">

    <interceptors>
      <interceptor-stack name="minimal">
        <interceptor-ref name="staticParams">
          <param name="parse">true</param>
        </interceptor-ref>
        <interceptor-ref name="params"/>
      </interceptor-stack>
    </interceptors>

    <action name="Image" class="org.chop.prjx.actions.ThumbnailAction">
      <interceptor-ref name="minima"/>

      <param name="buffSize">4096</param>

      <result type="stream">
        <param name="contentType">${mimeType}</param>
        <param name="contentLength">${length}</param>
        <param name="contentDisposition">inline; filename="${fileName}"</param>
        <param name="inputName">inputStream</param>
        <param name="bufferSize">${buffSize}</param>
        <param name="allowCaching">false</param>
      </result>
    </action>

    <action name="*">
      <result>/{1}.jsp</result>
    </action>

  </package>

</struts>

My idea was to be able to adjust the buffer size depending on
filesystem block size, average thumbnail size or whatever. However,
when invoking the action something bad happens:

GRAVE: Unable to set parameter [bufferSize] in result of type
[org.apache.struts2.dispatcher.StreamResult]
Caught OgnlException while setting property 'bufferSize' on type
'org.apache.struts2.dispatcher.StreamResult'. - Class:
ognl.OgnlRuntime
File: OgnlRuntime.java
Method: callAppropriateMethod
Line: 810 - ognl/OgnlRuntime.java:810:-1
    at 
com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:392)
    at com.opensymphony.xwork2.ognl.OgnlUtil.setProperty(OgnlUtil.java:143)
    at 
com.opensymphony.xwork2.ognl.OgnlReflectionProvider.setProperty(OgnlReflectionProvider.java:91)
    at com.opensymphony.xwork2.ObjectFactory.buildResult(ObjectFactory.java:221)
    at 
com.opensymphony.xwork2.DefaultActionInvocation.createResult(DefaultActionInvocation.java:208)
    ...
Caused by: java.lang.NoSuchMethodException: setBufferSize(java.lang.String)
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:810)
    at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:964)
    at 
ognl.ObjectPropertyAccessor.setPossibleProperty(ObjectPropertyAccessor.java:75)
    at ognl.ObjectPropertyAccessor.setProperty(ObjectPropertyAccessor.java:131)
    at 
com.opensymphony.xwork2.ognl.accessor.ObjectAccessor.setProperty(ObjectAccessor.java:28)
    ... MUCH more

I've been peeking a little into
org.apache.struts2.dispatcher.StreamResult, and it indeed has a
property bufferSize of type int, but looks like OGNL keeps on
hammering a non-existent String one.
By the way, I also can't get the point of contentLengh being String.
In struts.xml, if instead of:
        <param name="bufferSize">${buffSize}</param>
I put:
        <param name="bufferSize">4096</param>
Then everything's ok, but it's something that's itching me. That, and
the fact that ThumbnailAction.setBuffSize() is invoked twice.

Well, I think that's all. Please excuse this long post. Any ideas?

Regards

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org

Reply via email to