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: [email protected]
For additional commands, e-mail: [email protected]