Re: newbie questions - desparate need of help!!!

Todd Hivnor <[email protected]> Fri, 19 Jan 2007 19:09:02 -0800
Newsgroups gmane.comp.java.openamf.user
Message-ID <[email protected]>
I guess there are ways to run OpenAMF using your own custom servlet. But 
I use the "AdvancedGateway" provided by OpenAMF. Specifically I add the 
following to my web.xml file

    <servlet>
        <servlet-name>AdvancedGateway</servlet-name>
        <display-name>AdvancedGateway</display-name>
        <description>AdvancedGateway</description>
        <servlet-class>org.openamf.AdvancedGateway</servlet-class>
        <init-param>
            <param-name>OPENAMF_CONFIG</param-name>
                        
<param-value>/WEB-INF/openamf-config.xml</param-value>
            <description>Location of the OpenAMF config file.</description>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>AdvancedGateway</servlet-name>
        <url-pattern>/AdvancedGateway</url-pattern>
    </servlet-mapping>

Note the reference in web.xml which points to openamf-config.xml. This 
is a really powerful file so take the time to understand what it can do. 
It controls how the AdvancedGateway will behave. The 
<custom-class-mapping> can be used to send Objects in Java to Flash .. 
really cool stuff. The <state-bean> tag can be used to store persistent 
objects on the Java server. Or you can just make calls with simple Java 
primitives. Here are parts of my file, but beware it has a lot of stuff 
I'm not sure really needs to be there. I'm sure you can find a generic 
copy of a openamf-config.xml with the other OpenAMF files.

<?xml version="1.0" encoding="UTF-8"?>
<config>

    <!--
    Configure behavior of outgoing AMF messages:
    forceLowerCaseKeys - if true, the hash maps used to return custom 
classes
    will convert all keys to lower case;
    set this to:
        true if you're using ActionScript 1.0 on the client,
        false if you're using ActionScript 2.0 (which is case-sensitive)
    -->
    <amf-serializer>
            <force-lower-case-keys>false</force-lower-case-keys>
    </amf-serializer>

   <!--- include stock codes from openamf-config.xml file
         ... I don't what is needed and what isn't -->

   
    <invoker>
        <name>Java</name>
        <class>org.openamf.invoker.JavaServiceInvoker</class>
    </invoker>

    <service>
        <name>TestService</name>
        <service-location>com.example.TestService</service-location>
        <invoker-ref>Java</invoker-ref>
       
        <method>
            <name>*</name>
            <parameter>
                <type>*</type>
            </parameter>
        </method>
    </service>

    <custom-class-mapping>
          <java-class>com.example.Person</java-class>
        <custom-class>com.example.Person</custom-class>
    </custom-class-mapping>
</config>

The Java side now just

public class TestService {
    public static String getString(String s) { return "Hello " + s; }
    public static Person getPerson(String name) { return new 
Person(name); } // Define a Person class in both Java and Flash, and you 
can send them back & forth. Sweet!
}

On the Flash side you seem to have the clues. But I would be careful 
with case on your class names: "servlet1" != "Servlet1" And the Strings 
are particularly unequal because "simpleservlet.servlet1 " has a 
trailing space. Don't screw things like that up ... you are in the big 
league now with all this fancy client/server business :)

BEFORE
myService = new Service( "http://localhost:8083/WebModule1/", 
myLogger,"simpleservlet.servlet1 ", null,this);

AFTER
myService = new Service( "http://localhost:8083/WebModule1/", myLogger, 
"com.example.AdvancedGateway", null,this);

var pendingCall : PendingCall = myService.getString("Dork");


To support sending Person objects in both directions (From Java to Flash 
and vice-versa), add this on the Flash side:

Object.registerClass("com.example.Person", com.example.Person);
var pendingCall : PendingCall = myService.getPerson("Dork Face");
       
To learn more about mapping custom objects from Flash to Java, Google 
"carbonfive astranslator" I know you are simply trying to get started 
... but I personally think the Object mapping stuff is so cool is bears 
a little extra promotion. It is absolutely worth learning. Once you get 
past Hello Dork, of course.

If you do decide to send Objects from Flash to Java, beware of 
recursion. You can lock the Flash Player up if you send objects with 
circular references from Flash to Java. Oddly, you can send such objects 
from Java to Flash. Here is some ActionScript code I use to check for 
recursion, before trying to send the object to Java.


    /** Return true of the object is Ok.
     * Also return true if we are not currently checking for recursion.
     * If there is a problem trace it, and set the problematicObject 
variable
     */
     
    private static var problematicObject;
    public static function recursionCheck(currObject : Object) : Boolean {
        if (DebugConfig.checkRecursionInEvents()) {
            trace(Log.L_INFO+ "Performing Recursion Check ...");
            var result : Boolean = 
TestService.recursionCheckHelper(currObject, new Array());
           
            if (result) {
                trace(Log.L_INFO+ "Recursion Check Passed! ");
            }
            return result;
        } else {
            return true;
        }
    }

    private static function recursionCheckHelper(currObject : Object, 
objectsFound : Array) : Boolean {   
        var childObject : Object;
        var i : Number;
        var hasError : Boolean = false;
        for (var key : String in currObject) {
            childObject = currObject[key];
            if ( (typeof(childObject) == "object") || 
(typeof(childObject) == "movieclip"))  {
                for (i=0; i<objectsFound.length; i++) {
                    if (childObject == objectsFound[i]) {
                        trace(Log.L_ERROR+ "Found recursive child 
object=" + childObject + " with key=" + key + " in object=" + currObject 
+ " inside runEvent.");
                        TestService.problematicObject =childObject;
                        return false;
                    }
                }
                objectsFound.push(childObject);
               
                // recursively check
                if (recursionCheckHelper(childObject, objectsFound) == 
false) {
                    hasError = true;
                    break;
                }
                   
            } else if (childObject == null) {
                // no need to check null's
            } else if (
                (typeof(childObject) == "string") || 
                (typeof(childObject) == "boolean") || 
                (typeof(childObject) == "number") || 
                (typeof(childObject) == "function")
                ) {
                // no need to check these things


            } else {
                trace(Log.L_ERROR+ "Not an object: child object=" + 
childObject + " is " + typeof(childObject) + " with key=" + key + " in 
object=" + currObject + " inside runEvent.");
            }
        }
        return ! hasError;
    }



[p e r c e p t i c o n] wrote:
> Hi all
>
> i'm having some difficulty making flash remoting work.  I tried the 
> "Hello World" example from the OPENAMF examples to no avail and can't 
> seem to invoke any method other than doPost...which is fine if you can 
> tell me how to send a response back to the client (swf) i called it 
> from. I noticed while debugging my swf that the content-type is 
> application/x-fcs and my responder is null until pending call sets it 
> to _level0.  is there a way to change this content-type to something 
> else and if so what should it be?  I'll list my code and configuration 
> below. is there an easier way to do this? should i not use a servlet??
>
> config
> borland jbuilder 2005
> tomcat 5.0.27
> jdk 1.4.2
> Flash8
>
> here's my actionscript code
>
> import mx.remoting.Service;
> import mx.services.Log;
> import mx.rpc.RelayResponder;
> import mx.rpc.FaultEvent;
> import mx.rpc.ResultEvent;
> import mx.remoting.PendingCall; 
>
> mx.remoting.debug.NetDebug.initialize(); // initialize the 
> NetConnection Debugger
> var myLogger:Log = new Log( Log.DEBUG, "logger1" );
>
> // override the default log handler
> myLogger.onLog = function( message:String ):Void {
>  trace( "myLogger-->>>"+message );
> }
> //Create the service ->based on back-end used, comment/uncoment 
> following arguments
> myService = new Service( "http://localhost:8083/WebModule1/", 
> myLogger,"simpleservlet.servlet1 ", null,this);
>
>
> //Handler for results
> function onEchoData(msg: ResultEvent){
>     mx.remoting.debug.NetDebug.trace({level:"Debug", 
> message:"onEchoData" });
>     show.text = msg.result;
>
> }
> //Handler for errors
> function onEchoFault(rs: FaultEvent ){
>     mx.remoting.debug.NetDebug.trace({level:"None", message:"There was 
> a problem: " + fault.fault.faultstring });
>     }
> //Buttons handlers
> callButton.onPress = function(){
>    var pc:PendingCall = myService.makeEcho("Hello World!");
>    pc.responder = new RelayResponder(this._parent, "onEchoData", 
> "onEchoFault" );
>
>    trace("calling makeEcho");
> }
>
>
>
> and here's the java code
>
>
>
> package simpleservlet;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
> import java.io.*;
> import java.util.*;
> import org.apache.commons.io.*;
> import org.apache.commons.fileupload.*;
> import org.apache.commons.fileupload.disk.*;
> import org.apache.commons.fileupload.servlet.*;
> import magick.DrawInfo;
> import magick.MagickImage;
> import magick.PixelPacket;
> import magick.ImageInfo;
> import magick.MagickException;
> import flashgateway.io.ASObject;
> import org.openamf.*;
> import com.carbonfive.flash.ASTranslator;
>
>
> public class Servlet1
>     extends HttpServlet {
>
>    private String dirName;
>    private String fullPath;
>    private String message = null;
>   
>   public Servlet1() {
>     try {
>       jbInit();
>       System.out.println("ctor sucess");
>     }
>     catch (Exception ex) {
>       ex.printStackTrace();
>       System.out.println("ctor failure");
>     }
>   }
>
>   private static final String CONTENT_TYPE = "text/html";
>
>   //Initialize global variables
>   int connections = 0;
>
>   public void init() throws ServletException {
>     System.out.println("init");
>     message = "Hello from servlet1";
>   }
>
>
>   public String makeEcho(String msg)
>   {
>
>      return msg;
>   }
>
>
>   //Process the HTTP Get request
>   public void doGet(HttpServletRequest request, HttpServletResponse 
> response) throws
>       ServletException, IOException {
>     //Name of User
>     String userName = request.getParameter("UserName");
>     if (userName == null) {
>          userName = "User!";
>       }
>   }
>
>   //Process the HTTP Post request
>   public void doPost(HttpServletRequest request, HttpServletResponse 
> response) throws
>       ServletException, IOException
>   {
>
>     }
>
>
>
>   //Clean up resources
>   public void destroy() {
>     message = null;
>   }
>  
>  
>   public String getServletInfo()
>    {
>      return "A test servlet.";
>    }
>    public ServletConfig getServletConfig()
>    {
>      return null;
>    }
>  
>
>   private void jbInit() throws Exception {
>    
>    
>  
>  
>   }
>
> }
>
> thanks in advance
>
> p
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> ------------------------------------------------------------------------
>
> _______________________________________________
> Openamf-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/openamf-user
>   


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV