How to access session and request from Java service

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How to access session and request from Java service

X Gylee
In services.xml, I defined a service of type "java". According to
OFBiz documentation, this service received DispatchContext and Map as
its parameters.
How can I access the HTTP session and request from those input parameters?

I could not find an example in the OFBiz source about it. All the
codes in the source use the event of type "java" in controller.xml,
and this obviously provides HttpServletRequest as one of its input
parameters.
Reply | Threaded
Open this post in threaded view
|

RE: How to access session and request from Java service

SkipDever
As a general rule, services do not have a request or response in their
context (although you can certainly put them in if you need to).  Consider
that a service can be scheduled to run at 12AM in response to a job
scheduler and not an HTTP request.

You can call a service from you controller.xml file.  It can also be called
from the service scheduler, run synchronously or asynchronously from some
argitrary piece of java code, etc.

If you need the HttpServletRequest, you can get it from your controller like
this:

    <request-map uri="changeDelegator">
        <event type="java" path="org.ofbiz.webapp.event.CoreEvents"
invoke="changeDelegator"/>
        <response name="success" type="view" value="main"/>
        <response name="error" type="view" value="error"/>
    </request-map>

In this case, if you look at the changeDelegator() method, you will see that
it gets passed a request and response.  You will also note that
changeDelegator() is not to be found in a service.xml file(unless there just
happens to be a service with the same name)  because it is not a service.

In your services.xml file, you can require that it be called with a request
and a response in the context if that is what your needs are.

Hope this helps

Skip

-----Original Message-----
From: X Gylee [mailto:[hidden email]]
Sent: Monday, November 19, 2007 3:02 AM
To: [hidden email]
Subject: How to access session and request from Java service


In services.xml, I defined a service of type "java". According to
OFBiz documentation, this service received DispatchContext and Map as
its parameters.
How can I access the HTTP session and request from those input parameters?

I could not find an example in the OFBiz source about it. All the
codes in the source use the event of type "java" in controller.xml,
and this obviously provides HttpServletRequest as one of its input
parameters.

Reply | Threaded
Open this post in threaded view
|

RE: How to access session and request from Java service

X Gylee
In reply to this post by X Gylee
Skip,
Thank you for your explanation. That explains better the design
paradigm in OFBiz. I might need to re-think my application design
then.

However, to understand better, can you elaborate what you said in your
response? how can I do the following?

You wrote:
As a general rule, services do not have a request or response in their
context (although you can certainly put them in if you need to).
...
In your services.xml file, you can require that it be called with a request
and a response in the context if that is what your needs are.
Reply | Threaded
Open this post in threaded view
|

RE: How to access session and request from Java service

SkipDever
Xman

Suggest that you first have a look at:
http://ofbiz.apache.org/docs/services.html

With this, you can gain an understanding of what a service actually is in
Ofbiz.  In a nutshell, it is basically only a piece of public static code
that takes the arguments DispatchContext dctx and Map context.  The engine
supplies the DispatchContext and you supply the Map.  The contents of the
context map are whatever you specified in the service definition and
prepared before hand before making the call.  Here is a sample of a service
definition from accounting/servicedef/services_payment.xml:

    <service name="setPaymentStatus" engine="simple"
default-entity-name="Payment"
        location="org/ofbiz/accounting/payment/PaymentServices.xml"
invoke="setPaymentStatus" auth="true">
        <description>Change the status of a Payment</description>
        <auto-attributes include="pk" mode="IN" optional="false"/>
        <attribute name="statusId" type="String" mode="IN"
optional="false"/>
        <attribute name="oldStatusId" type="String" mode="OUT"
optional="true"/>
    </service>

Note the <attribute> tag and the mode="IN" and optional="false".  This sez
that the attribute MUST be supplied in the context map.  Failure to do so
results in an error.  I can call this service in a java program like this:

        Map results = dispatcher.runSync("setPaymentStatus",
UtilMisc.toMap("userLogin", demofinadmin, "paymentId",
paycheck.get("paymentId"), "statusId", "PMNT_SENT"));

I can call it from a simple method like this:

...
        <if-not-empty field-name="parameters.StatusId">
            <if-compare-field field-name="parameters.statusId"
operator="not-equals" to-field-name="statusIdSave">
                <set-service-fields service-name="setPaymentSatus"
map-name="parameters" to-map-name="param"/>
                <call-service service-name="setPaymentStatus"
in-map-name="param"/>
                <check-errors/>
            </if-compare-field>
        </if-not-empty>

I can call it in my controller like this:

    <request-map uri="setPaycheckStatus">
        <security https="true" auth="true"/>
        <event type="service" invoke="setPaymentStatus"/>
        <response name="success" type="request-redirect"
value="viewPaycheck"/>
        <response name="error" type="view" value="viewPaycheck"/>
    </request-map>

If I call it from the controller as above, I MUST make sure the required
attributes are available as parameters of the request.

Note that "setPaymentStatus" has the java signiture:
public static Map setPaymentStatus(DispatchContext dctx, Map context)
(although this particular one is a simple method).

If you enumerate all the items in the context map, nowhere will you find
HttpServletRequest or HttpServletResponse in any that I know of and for sure
not in this example.  You could however require these like this:

    <service name="myHTTPResponseReader" engine="java"
        location="org/ofbiz/mystuff/httpStuff" invoke="myHTTPResponseReader"
auth="true">
        <description>My HTTP stuff</description>
        <attribute name="request"
type="javax.servlet.http.HttpServletRequest" mode="IN" optional="false"/>
    </service>

Have a look here: https://localhost:8443/webtools/control/availableServices
and you can see all the services that Ofbiz knows about.

If you are trying to manipulate web page content, I don't think a service is
what you really want (unless you want to perform some action as the result
of some operator action).

If you want to do something servlet style, you can create a method with this
signature:

    public static String myServlet(HttpServletRequest request,
HttpServletResponse response)

and call it like this:

    <request-map uri="myURI">
       <event type="java" path="org.ofbiz.myServlet" invoke="myServlet"/>
       <response name="fail" ..."/>
       <response name="success" ..."/>
    </request-map>

You would NOT call it with dispatcher.runSync() because it is NOT a service
in the Ofbiz sense.


Note the type="java" here and for a service as show above, type="service".

The servlet code like this does not need to be defined in any service.xml
file and in fact doesn't really want to be.

Hope this helps.

Skip



-----Original Message-----
From: X Gylee [mailto:[hidden email]]
Sent: Monday, November 19, 2007 7:33 PM
To: [hidden email]
Subject: RE: How to access session and request from Java service


Skip,
Thank you for your explanation. That explains better the design
paradigm in OFBiz. I might need to re-think my application design
then.

However, to understand better, can you elaborate what you said in your
response? how can I do the following?

You wrote:
As a general rule, services do not have a request or response in their
context (although you can certainly put them in if you need to).
...
In your services.xml file, you can require that it be called with a request
and a response in the context if that is what your needs are.

Reply | Threaded
Open this post in threaded view
|

Re: How to access session and request from Java service

X Gylee
In reply to this post by X Gylee
Skip,
Your explanation cleared things up a lot.
I tried your suggestion to include an attribute to my "java service",
so that I will have the request in the context.

<attribute name="request" type="javax.servlet.http.HttpServletRequest"
mode="IN" optional="false"/>

However, since the form before it does not have any value to be
submiited, the service compains about missing the required parameter
"request". What value should I submit to the service?

Moreover, I found out that any context-param value from web.xml was
not included in the context of a "service". They are accessible only
if I use a "java event", via its servlet-type HttpServletRequest.

However, context-params are accessible from the map "parameters" in
the screen widget and form widget. Is there a way to access them in a
"service"? Or, what is the best practice to access a predefined
variable (such as a context-param) from a "service"?

Many thanks for your help.
Reply | Threaded
Open this post in threaded view
|

RE: How to access session and request from Java service

SkipDever
X-man

See my comments below

-----Original Message-----
From: [hidden email] [mailto:[hidden email]]
Sent: Tuesday, November 20, 2007 4:18 AM
To: [hidden email]
Subject: Re: How to access session and request from Java service


Skip,
Your explanation cleared things up a lot.
I tried your suggestion to include an attribute to my "java service",
so that I will have the request in the context.

<attribute name="request" type="javax.servlet.http.HttpServletRequest"
mode="IN" optional="false"/>

However, since the form before it does not have any value to be
submiited, the service compains about missing the required parameter
"request". What value should I submit to the service?

>>>>>These values in the context map do not get their by magic.  YOU, the
developer have to make sure they get stuck there.  As I mentioned, you will
find no service that I know of that has a HttpServletRequest in the context
Map.  Once again, I suggest that you use the "java" type in your
controller.xml file instead of the "service".


Moreover, I found out that any context-param value from web.xml was
not included in the context of a "service". They are accessible only
if I use a "java event", via its servlet-type HttpServletRequest.

>>>>I suggest that you use the "java" type in your controller.xml file
instead of the "service".

However, context-params are accessible from the map "parameters" in
the screen widget and form widget. Is there a way to access them in a
"service"? Or, what is the best practice to access a predefined
variable (such as a context-param) from a "service"?

>>>>You cannot get them in a service.  That is not what a service is.  I
suggest that you use the "java" type in your controller.xml file instead of
the "service".

Many thanks for your help.