Service Context

The ServiceContext class is a parameter class used for passing contextual information for a service. Using a parameter class lets you consolidate many different methods with different sets of optional parameters into a single, easier-to-use method. The class also aggregates information necessary for transversal features, including permissioning, tagging, categorization, and more.

In this section we’ll look at the Service Context fields, learn how to create and populate a Service Context, and learn to access Service Context data.

First we’ll look at the fields of the ServiceContext class.

Service Context Fields

The ServiceContext class has many fields. The best field descriptions are found in the Javadoc:

http://docs.liferay.com/portal/6.1/javadocs-all/com/liferay/portal/service/ServiceContext.html.

Here we’ll give you a helpful categorical listing of the fields:

  • Actions:
    • _command
    • _workflowAction
  • Attributes:
    • _attributes
    • _expandoBridgeAttributes
  • Classification:
    • _assetCategoryIds
    • _assetTagNames
  • IDs and Scope:
    • _companyId
    • _portletPreferencesIds
    • _plid
    • _scopeGroupId
    • _userId
    • _uuid
  • Language:
    • _languageId
  • Miscellaneous:
    • _headers
    • _signedIn
  • Permissions:
    • _addGroupPermissions
    • _addGuestPermissions
    • _deriveDefaultPermissions
    • _groupPermissions
    • _guestPermissions
  • Resources:
    • _assetEntryVisible
    • _assetLinkEntryIds
    • _createDate
    • _indexingEnabled
    • _modifiedDate
  • URLs, paths and addresses:
    • _currentURL
    • _layoutFullURL
    • _layoutURL
    • _pathMain
    • _portalURL
    • _remoteAddr
    • _remoteHost
    • _userDisplayURL

Are you wondering how the ServiceContext fields get populated? Good! We’ll show you that next.

Creating and Populating a Service Context

Although all the ServiceContext class fields are optional, services that store any type of content need the scope group ID specified, at least. Here’s a simple example of creating a ServiceContext instance and passing it as a parameter to a service API using Java:

    ServiceContext serviceContext = new ServiceContext();
    serviceContext.setScopeGroupId(myGroupId);
    ...
    BlogsEntryServiceUtil.addEntry(...., serviceContext);

If you invoke the service from a servlet, a Struts action or any other front end class which has access to the PortletRequest, use one of the ServiceContextFactory.getInstance(...) methods. These methods create the ServiceContext object and automatically fill it with all necessary values. The above example looks different if you invoke the service from a servlet:

    ServiceContext serviceContext =
            ServiceContextFactory.getInstance(BlogsEntry.class.getName(),
            portletRequest);
    BlogsEntryServiceUtil.addEntry(..., serviceContext);

You can see an example of populating a ServiceContext with information from a request object in the code of the ServiceContextFactory.getInstance(...) methods. The methods demonstrate how to set parameters like scope group ID, company ID, language ID, and more; they also demonstrate how to access and populate more complex context parameters like tags, categories, asset links, headers, and the attributes parameter. By calling ServiceContextFactory.getInstance(String className, PortletRequest portletRequest), you can assure your expando bridge attributes are set on the ServiceContext.

Next let’s see an example of accessing information from a ServiceContext.

Accessing Service Context data

We’ll use code snippets from BlogsEntryLocalServiceImpl.addEntry(..., ServiceContext) to show you how to access information from a ServiceContext and comment on how the context information is being used.

As we mentioned, your service needs a scope group ID from your ServiceContext. The same holds true for the blogs entry service because the scope group ID provides the scope of the blogs entry (the entity being persisted). For the blogs entry, the scope group ID is used in the following way:

  • It’s used as the groupId for the BlogsEntry entity.
  • It’s used to generate a unique URL for the blog entry.
  • It’s used to set the scope for comments on the blog entry.

Here are the corresponding code snippets:

    long groupId = serviceContext.getScopeGroupId();
    ...
    entry.setGroupId(groupId);
    ...
    entry.setUrlTitle(getUniqueUrlTitle(entryId, groupId, title));
    ...

    // Message boards

    if (PropsValues.BLOGS_ENTRY_COMMENTS_ENABLED) {
        mbMessageLocalService.addDiscussionMessage(
            userId, entry.getUserName(), groupId,
            BlogsEntry.class.getName(), entryId,
            WorkflowConstants.ACTION_PUBLISH);
    }

Can ServiceContext be used to access the UUID of the blog entry? Absolutely! Can you use ServiceContext to set the time the blog entry was added? Sure you can. See here:

    entry.setUuid(serviceContext.getUuid());
    ...
    entry.setCreateDate(serviceContext.getCreateDate(now));

Can ServiceContext be used in setting permissions on resources? You bet! When adding a blog entry, you can add new permissions or apply existing permissions for the entry, like this:

    // Resources

    if (serviceContext.isAddGroupPermissions() ||
        serviceContext.isAddGuestPermissions()) {

        addEntryResources(
            entry, serviceContext.isAddGroupPermissions(),
            serviceContext.isAddGuestPermissions());
    }
    else {
        addEntryResources(
            entry, serviceContext.getGroupPermissions(),
            serviceContext.getGuestPermissions());
    }

ServiceContext helps apply categories, tag names, and the link entry IDs to asset entries too.

    // Asset

    updateAsset(
        userId, entry, serviceContext.getAssetCategoryIds(),
        serviceContext.getAssetTagNames(),
        serviceContext.getAssetLinkEntryIds());

Does ServiceContext also play a role in starting a workflow instance for the blogs entry? Must you Ask?

    // Workflow

    if ((trackbacks != null) && (trackbacks.length > 0)) {
        serviceContext.setAttribute("trackbacks", trackbacks);
    }
    else {
        serviceContext.setAttribute("trackbacks", null);
    }

    WorkflowHandlerRegistryUtil.startWorkflowInstance(
        user.getCompanyId(), groupId, userId, BlogsEntry.class.getName(),
        entry.getEntryId(), entry, serviceContext);

The snippet above also demonstrates the trackbacks attribute, a standard attribute for the blogs entry service. There may be cases where you need to pass in custom attributes to your blogs entry service. Use Expando attributes to carry custom attributes along in your ServiceContext. Expando attributes are set on the added blogs entry like this:

    entry.setExpandoBridgeAttributes(serviceContext);

You can see that the ServiceContext can be used to transfer lots of useful information for your services.

Let’s look at Message Bus next.

« JSON Web ServicesUsing Message Bus »
这篇文章有帮助吗?
0 人中有 0 人觉得有帮助