1. Extending DCErrorHandlerImpl-
for model
Custom ExceptionHandler
Class for model
package
xx.view.exp.model;
import
javax.faces.application.FacesMessage;
import
oracle.adf.model.binding.DCErrorHandlerImpl;
import
oracle.adf.model.BindingContext;
import
oracle.adf.model.binding.DCBindingContainer;
import
oracle.jbo.JboException;
public
class XxModelExpHandler
extends DCErrorHandlerImpl
{
public XxModelExpHandler()
{
super(true);
}
public XxModelExpHandler(boolean b)
{
super(b);
}
@Override
public String getDisplayMessage(BindingContext ctx, Exception th)
{
return super.getDisplayMessage(ctx, th);
}
@Override
public void reportException(DCBindingContainer formBnd, Exception ex)
{
if (ex instanceof XxCustomException)
{
//get
message to be displayed from resource bundle or hardcode the message when
throwing exception
String msg = XxUtils.getMessageString((XxCustomException)
ex);
JboException jex=new JboException(msg);
super.reportException(formBnd,jex);
}
else
{
super.reportException(formBnd, ex);
}
}
}
Databindings.cpx
Specify
your custom handler as ErrorHandlerClass in databindings.cpx:
<Application
xmlns="http://xmlns.oracle.com/adfm/application"
version="11.1.1.59.23"
id="DataBindings" SeparateXMLFiles="false"
Package="xx.view"
ClientType="Generic"
ErrorHandlerClass="xx.view.exp.model.XxModelExpHandler">
2. Extending Controller
level ExceptionHandler
Any
exception in controller will first come here and if re-thrown will be handled
at taskflow level(explained before).
Declaring custom exception
handler class
You
need to create a folder named services under Application Resources ->
Descriptors -> ADF META-INF. Under the folder create a file named
oracle.adf.view.rich.context.ExceptionHandler and inside the file just mention
the name of your custom exception handler.
Custom Exception Class
We are
creating a custom exception class which will be thrown in our code whenever we
want to show a faces message for any validation, failure, etc.
public
class XxCustomException
extends JboException
{
private String resourceBundleKey;
private String error_type;
private String client_id;
private MessageToken[] tokens;
//setters
and getters with required constructors
}
Custom ExceptionHandler
Class
import
oracle.adf.view.rich.context.ExceptionHandler;
public
class XxControllerExpHandler
extends ExceptionHandler
{
public void handleException(FacesContext facesContext,
Throwable throwable, PhaseId phaseId)
throws Throwable
{
boolean
isCustomExp = false;
for (int i = 0; i < 10; i++)
{
if (throwable instanceof XxCustomException)
{
isCustomExp = true;
break;
}
if (throwable != null)
{
throwable = throwable.getCause();
}
}
if (isCustomExp)
{
if (throwable!= null)
{
// The below method will show a Faces Message. If
client id of xxCustomException is not null then it will show a faces message on
that component. It will try to get the message from resource bundle based
on resourceBundleKey attribute. Error_type will decide if it is info,
warning, severe
XxUtils.showMessage((XxCustomException)throwable);
}
}
else
{
//this
will be handled at taskflow level
throw z;
}
}
3.
Taskflow Exception Handler
Here We will discuss on session timeout
and exception handling for at taskflow level by creating an Exception Handler
Task Flow changes
Create
a router in your taskflow:
Add a
condition which points to a method in backing bean.
The
method returns true if session expires and user is redirected to home/login
page as needed.
And if
method returns false, the user is redirected to default outcome - errorPage.
Mark
the router as exception handler
BEAN changes
Add the
following method in your bean:
public boolean isSessionExpired()
{
Exception e =
ControllerContext.getInstance().getCurrentViewPort().getExceptionData();
if (e != null && (e instanceof ViewExpiredException))
{
//
session timeout case
return true;
}
// IF
SOA is down or some other fault in SOA process
else if (e != null &&
(e instanceof ConnectException || e
instanceof javax.xml.ws.WebServiceException ||
e instanceof
javax.xml.ws.soap.SOAPFaultException || e.toString().contains("Failed to
access the WSDL")))
putParameterinPageFlowScope("errorMessage",
"Currently the system is in maintenance
mode. Please try after sometime.");
else
putParameterinPageFlowScope("errorMessage",
"Some unexpected error has occurred.
Please try after sometime.");
if (e != null)
{
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
if(errors != null)
putParameterinPageFlowScope("detailedException",errors.toString());
}
return false;
}
Note:
In case where there is an exception other than
ViewExpiredException(session timeout), write two parameters in request or
pageFlowScope as written above:
·
Put Parameter in PageFlowScope("errorMessage",
"Currently the system is in maintenance mode. Please try after
sometime.");
·
Put Parameter in PageFlowScope ("detailedException",errors.toString());
Error Page
<af:outputFormatted
value="#{pageFlowScope.errorMessage}"/>
<af:outputFormatted
value="#{pageFlowScope.detailedException}"
visible="false"/>
Note:
visible="false" makes sure the detailed
exception is there in source of the page and user doesn`t see it.
You can see the same in page source.
You can add more conditions and messages in your bean
method based on your scenarios like Content Server related exceptions, oim
client,Bpm related etc.
For any issue in implementation please comments.
Thanks
No comments:
Post a Comment