![]() ![]() ![]() ![]() |
Referrals |
If you set the Context.REFERRAL("java.naming.referral") environment property to "throw", then each referral encountered results in a ReferralException
. A ReferralException contains referral information, which is information that describes the referral (such as a list of URLs), and a referral context, which is the context that the referral refers to. Here are the steps that a program usually follows when manually handling referrals:
- Catch the exception.
- Examine the referral information using ReferralException.getReferralInfo()
. For example, ask the user whether the referral should be followed.
- If the referral is to be followed, get the referral context using ReferralException.getReferralContext()
and reinvoke the original context method using the same arguments supplied to the original invocation.
- If the referral is not to be followed, invoke ReferralException.skipReferral()
. If this method returns true (which means that there are more referrals to be followed), then invoke ReferralException.getReferralContext() to continue. When you invoke a context method on the result, it will again throw a ReferralException for the next referral to be processed. Return to Step 1 to process it. If the method returns false, there are no more referrals and this procedure can be terminated.
Here's an example:
For methods that return an enumeration, such as Context.list()// Set referral property to throw ReferralException env.put(Context.REFERRAL, "throw"); // Create initial context DirContext ctx = new InitialDirContext(env); // Set controls for performing subtree search SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Do this in a loop because we don't know how // many referrals there will be for (boolean moreReferrals = true; moreReferrals;) { try { // Perform search NamingEnumeration answer = ctx.search("", "(objectclass=*)", ctls); // Print the answer while (answer.hasMore()) { System.out.println(">>>" + ((SearchResult)answer.next()).getName()); } // search completes with no more referrals moreReferrals = false; } catch (ReferralException e) { if (! followReferral(e.getReferralInfo())) { moreReferrals = e.skipReferral(); } // point to the new context if (moreReferrals) { ctx = (DirContext) e.getReferralContext(); } } }and DirContext.search()
, you must place the try/catch for ReferralException around both the initial invocation and the while loop that iterates through the results. When the ReferralException is thrown, the existing enumeration becomes invalid and you must reinvoke the original context method to get a new enumeration. Notice also that the outer loop encloses both the method invocation on the context and the iteration of the results.
Authenticating to a Referral Context
By default, when you invoke ReferralException.getReferralContext(), the method uses the original context's environment properties, including its security-related properties, to create a connection to the referred server. Sometimes, upon examining the referral information, you might want to follow the referral using different authentication information.You can do this by using ReferralException.getReferralContext(env)
:
If the authentication fails, that is, getReferralContext(env) throws an exception, you can reauthenticate by first calling ReferralException.retryReferral()... } catch (ReferralException e) { ... env.put(Context.SECURITY_PRINCIPAL, "newuser"); env.put(Context.SECURITY_CREDENTIALS, "newpasswd"); ctx = e.getReferralContext(env); }and then repeating the getReferralContext(env) call with updated environment properties. If you do not want to retry, invoke ReferralException.skipReferral() before calling getReferralContext(env).
Here is an example:
In this example, the e.getReferralContext(env) call is placed inside a loop, so that if the call fails, it can be retried using different credentials. The example defines a local method, getCreds(), for getting the principal name and credentials from Standard Input to update the environment properties, env, that are being used to get the referral context. When e.getReferralContext(env) fails, the user of the application can either choose to retry using different credentials, or skip the bad referral.... } catch (ReferralException e) { if (!ask("Follow referral " + e.getReferralInfo())) { moreReferrals = e.skipReferral(); } else { // Get credentials for referral being followed getCreds(env); } // Do this in a loop in case getReferralContext() // fails with bad authentication info. while (moreReferrals) { try { ctx = (DirContext)e.getReferralContext(env); break; // success: got context } catch (AuthenticationException ne) { if (ask("Authentication failed. Retry")) { getCreds(env); e.retryReferral(); } else { // give up and go on to next referral moreReferrals = e.skipReferral(); } } catch (NamingException ne) { System.out.println("Referral failed: " + ne); // give up and go on to next referral moreReferrals = e.skipReferral(); } } }Passing Request Controls To a Referral Context
See the Controls and Extensionslesson for details on how to set and change request controls of a referral context.
![]() ![]() ![]() ![]() |
Referrals |