JSON Web Services

NOTE: This document is not maintained any more. It has been moved to official Liferay development guide: https://github.com/liferay/liferay-docs/tree/master/devGuide

The idea behind JSON Web Services is to provide portal service methods as JSON API. This makes services methods easily accessible using HTTP request not only from portals javascript, but also from any JSON-speaking client out there.

This is not a new idea and the portal already contains an implementation that allows users calling services. This time we went one step further and developed an enhanced and more convenient and developer-friendly solution. Yay!

There are following parts of JSON Web Services functionality: registration, invocation and results. Each part will be discussed in more details.

Registering JSON Web Services #

By default, all remote-enabled services (i.e. with remote-service="true" on entity in service.xml) will be exposed as JSON web services. When Service Builder creates some Service.java interface, it will also add @JSONWebService annotation on class level in that service.

Therefore, when service interface is annotated with @JSONWebService annotation, all service methods becomes registered and available as JSON Web Services.

Service interface is generated file and it is recommended not be modified by user directly. Therefore, if user wants to manually control which methods to expose and to hide, he can do that in ServiceImpl class of that service. When service implementation class (ServiceImpl) is annotated with @JSONWebService annotation, interface will be ignored and only service implementation will be considered for configuration.

In other words, @JSONWebService annotations in service implementation overrides default configuration from service interface.

And that’s all! Upon start, portal scans all classes on classpath for annotation usage (don’t worry, portal scans raw class content and only jars and classes of interest are loaded, not all of them). Each class that uses the annotation is examined and its methods becomes exposed as JSON API. Registration follows explained rule: ServiceImpl are examined first and then Service interface, if necessary.

For example, let’s look the DLAppService:

@JSONWebService
 public interface DLAppService {
...

It contains the annotation that will be found when portal is started. Notice the following lines in console output:

10:55:06,595 DEBUG [JSONWebServiceConfigurator:121] Configure JSON web service actions
10:55:06,938 DEBUG [JSONWebServiceConfigurator:136] Configuring 820 actions in ... ms

At this point, registration is done and all service methods of DLAppService (and of other services as well) are registered as JSON Web Services.

Portlets #

Of course, custom portlets can be scanned, too, and their service can become part of the JSON API. For this you must add the following in portlets web.xml:

     <servlet>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet</servlet-class>
        <init-param>
            <param-name>servlet-class</param-name>
            <param-value>com.liferay.portal.jsonwebservice.JSONWebServiceServlet</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/jsonws/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/secure/jsonws/*</url-pattern>
    </servlet-mapping>

This enables the servlet that is responsible for scanning JSON web services configuration.

Do not forget: to access portlet JSON Web Services you must use portlet context path, for example: http://localhost:8080/<portlet>/api/..

List available JSON Web Services #

To overview and verify which service methods are registered and available, user can use following URL to list them all in browser (notice the ‘jsonws’ in the URL, it is relevant for all JSON Web Services calls - more on invocation later):

http://localhost:8080/api/jsonws

The result is a list of all registered and exposed service methods. For each method user can see more details, by clicking the method name. On method details page, user can even invoke the method  for testing purposes.

To list registered services on portlet, don't forget to use portlet contenxt path:

http://localhost:8080/<portlet>/api/jsonws

More on registration #

As said, user can control registration by using annotations in the ServiceImpl class. This completely overrides interface configuration. Moreover, user can fine-tune which methods are visible using annotations on method level.

Ignoring a method #

To ignore a method from an exposed service class, just annotated method with:

@JSONWebService(mode = JSONWebServiceMode.IGNORE)

Such methods will be not available as JSON api.

HTTP method name and URL #

As expected, it is also possible to define custom HTTP method name and URL names, using the same annotation.

@JSONWebService(value = "add-file-wow", method = "PUT")
public FileEntry addFileEntry(

In this example, method addFileEntry will be mapped to /dlapp/add-file-wow  (actually to the: /api/jsonws/dlapp/add-file-wow) and can be accessed using HTTP method PUT.

If URL name starts with a slash character (‘/’), only method name is used to form service URL; class name is ignored.

@JSONWebService("/add-something-very-specific")
public FileEntry addFileEntry(

Similarly, user can change the class name part of the URL, by setting the value in class-level annotation:

@JSONWebService("dla")
public class DLAppServiceImpl extends DLAppServiceBaseImpl {

Now all service methods would have 'dla' in the URL instead of default 'dlapp'.

Manual registration mode #

Up to now, it is expected that most of the service methods is going to be exposed and allowed user to ignore few. But sometimes user wants a different behavior: to explicitly specify only methods that are going to be exposed. This is possible, too, using so-called manual mode on class-level annotation. User then annotates only methods that has to be exposed.

@JSONWebService(mode = JSONWebServiceMode.MANUAL)
public class DLAppServiceImpl extends DLAppServiceBaseImpl {
...
@JSONWebService
public FileEntry addFileEntry(

Configuration #

JSON Web Services can be easily turned off in portal.properties by setting:

json.web.service.enabled=false

Strict HTTP methods #

JSON Web Service services will be binded to either GET or POST HTTP method. If service method is a read-only method, i.e. it which name starts with 'get', 'is' or 'has', service will be binded to GET method; otherwise it will be binded to POST.

By default, portal is not checking HTTP method for a service call, i.e. it works in "non-strict http method" mode. Meaning: services may be invoked using any HTTP method. If you need the strict mode, you can set it with:

jsonws.web.service.strict.http.method=true

Disabled HTTP methods #

When strict HTTP method is enabled, you can even filter the access based on HTTP methods. For example, you can set the portal JSON Web Services work only in read-only mode, by disabling POST (and other) HTTP methods. For example:

jsonws.web.service.invalid.http.methods=DELETE,POST,PUT

JSON Web Service Invocation #

All services are invoked through its Util classes, as you would use it from the java code.

JSON web services can be invoked in several ways depending on how parameters (i.e. method arguments) are sent.

Passing parameters as part of URL path #

Parameters can be passed as part of the URL path. After the service URL (defined by class and method annotations, as we've seen above) user can append method parameters (name/value pairs). Parameter names are formed form method argument names, by converting camel-case to lowercased separated-by-dash name. Example:

http://localhost:8080/api/secure/jsonws/dlapp/get-file-entries/repository-id/10172/folder-id/0

Parameters may be given in any order; it’s not necessary to follow arguments order as defined by methods.

When some method name is overloaded, the best match will be used - a method that contains the least of arguments undefined.

Passing parameters as URL query #

Parameters can be passed as request parameters, too. The difference is that now parameter names are equals to service method argument names:

http://localhost:8080/api/secure/jsonws/dlapp/get-file-entries?repositoryId=10172&folderId=0

Everything else remains the same, like order is not important, etc

Mixed way of passing parameters #

Parameters can be passed in mixed way: some can be part of the URL path and some can be specified as request parameters.

Sending NULL values #

To pass null value for some argument, simply prefix that parameter name with a dash '-'. For example:

.../dlsync/get-d-l-sync-update/company-id/10151/repository-id/10195/-last-access-date

Here the 'last-access-date' parameter will be null.

Null parameters, therefore, do not have a value specified. Of course, null parameters do not have to be the last one, as in this example.When passed as request parameter, its value will be ignored and null will be used instead:

<input type="hidden" name="-last-access-date" value=""/>

When using JSON RPC (see below), null values may be sent even without a prefix! For example:

"last-access-date" : null

Difference between URL and query encoding #

This is something often forgotten: there is a difference between URL and query (request parameters) encoding. Most illustrative difference is how space character is encoded. When space is part of the URL path it is encoded as %20, when it is part of the query it is encoded as plus sign (+).

Sending files as arguments #

Files can be uploaded using multipart forms and request. Example

<form action="http://localhost:8080/api/secure/jsonws/dlapp/add-file-entry" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="repositoryId" value="10172"/>
        <input type="hidden" name="folderId" value="0"/>
        <input type="hidden" name="title" value="test.jpg"/>
        <input type="hidden" name="description" value="File upload example"/>
        <input type="hidden" name="changeLog" value="v1"/>
        <input type="file" name="file"/>
        <input type="submit" value="addFileEntry(file)"/>
</form>

JSON RPC #

JSON Web Service may be invoked using JSON RPC. Good part of JSON RPC 2.0 specification is supported. Parameters may be passed only as named parameters, since positional are not supported - there are too many overloaded method for convenient use of positional parameters. Example:

POST http://localhost:8080/api/secure/jsonws/dlapp
{"method":"get-folders", "params":{"repositoryId":10172, "parentFolderId":0}, "id":123, "jsonrpc":"2.0"}

Default parameters #

If user is authenticated when accessing JSON web services, some parameters will be available by default. They do not need to be explicitly specified, only if we want to change their default value.

Default parameters are:

userId - id of authenticated user

user - full User object

companyId - users company

serviceContext - empty service context object

Object parameters #

Most services accept simple parameters: numbers, strings etc. However, sometimes we need to provide an object of non-simple type as an service parameter.

Simillary to null parameters and the '-' prefix, to create an instance of some parameter just prefix it with a plus sign, '+'. You don't have to specify any parameter at all. For example:

/jsonws/foo/get-bar/zap-id/10172/start/0/end/1/+type

or as request parameter (+ sign has to be encoded!):

/jsonws/foo/get-bar?zapId=10172&start=0&end=1&%2Btype

or

<input type="hidden" name="+type" value=""/>

If parameter is of abstract type or interface, it can't be created. We must specify the concrete implementation. This can be done by adding suffix to the parameter, for example:

/jsonws/foo/get-bar/zap-id/10172/start/0/end/1/+type:com.liferay.CoolType

or

<input type="hidden" name="+type:com.liferay.CoolType" value=""/>

But concerte implementation can be set as a value, too! For example:

<input type="hidden" name="+type" value="com.liferay.CoolType"/>

or in JSON RPC:

"+type" : "com.liferay.CoolType"

Map and List parameters #

Map and List parameters are also supported, by sending json objects and arrays. If parameters Map or List contains generic (e.g. Map<Locale, String>), then portal will generify the map/list before passing it to the method.

Inner Parameters #

In some cases it is needed to populate objects that are passed as parameters. A good example is a default parameter, serviceContext. Sometimes, we need to set some of its inner properties, such as: addGroupPermissions, scopeGroupId etc. to make a successful JSONWS call.

To pass inner parameters, just provide them using a 'dot' notation. For this example it means that you can provide: serviceContext.addGroupPermissions, serviceContext.scopeGroupId  parameters, together with others. Our engine will recognize them as inner parameters (they have a dot in the name) and will inject  their values into existing parameters, before API method is executed.

Inner parameters are not count as regular parameters for matching methods.

Note: use inner parameters with object parameters to set inner content of created parameter instances!

Matching service methods #

It is important to understand how service methods are matched from the url path, especially when some method is overloaded.

General rule is that besides the method name, user must provide all parameters as well. It is not important how parameters are provided (as part of the URL line or as request parameters...), neither the order is important. Even if some parameter will be null, you must provide it.

So, methods are matched by method and parameter names!

Note that inner parameters are ignored during matching.

Using hints #

It is also possible to add numeric hints that specifies how many method arguments service has. Hints are added as numbers separated by a dot in method name. For example:

/foo/method.2/param1/123/-param2

The '.2' here is a hint so only service methods with 2 arguments will be matched.

One important difference when hint is active is that now you do not have to specify all parameters. All missing arguments are treated as null. Therefore, previous example may be called as:

/foo/method.2/param1/123

since 'param2' is null.

Returned values #

No matter which way invoked, JSON web services return JSON string that represents service method result. Returned object is loosely serialized to JSON string and returned to calling client.

 NOTE: This document is not maintained any more. It has been moved to official Liferay development guide: https://github.com/liferay/liferay-docs/tree/master/devGuide

0 Allegati
58645 Visualizzazioni
Media (6 Voti)
La media del punteggio è 4.5 stelle su 5.
Commenti
Commenti Autore Data
Nice Wiki....can't wait to have my hands on it.. Jay Patel 30 maggio 2011 23.31
There is a missing part on the registration... Thiago Leão Moreira 31 maggio 2011 10.45
Hi Thiago Leão Moreira, i have a problem with... AA CC 8 giugno 2011 3.50
Hello, which Liferay Version do you need to use... Michael W 7 luglio 2011 1.29
page has been upgraded to reflect latest code... Igor Spasić 28 luglio 2011 5.48
thx a lot for upgrading the wiki :) Michael W 9 agosto 2011 2.42
@Igor When you say "this feature is part of... Michael Hartman 6 ottobre 2011 14.30
Hi Michael, and sorry, I am not quite aware... Igor Spasić 11 ottobre 2011 3.05
page is updated to reflect latest code changes... Igor Spasić 11 ottobre 2011 3.06
typically reiventing the wheel! Peter Fox 3 gennaio 2012 10.29
Using 6.1 GA1: I added the <servlet> and... Gerald Rubin 12 gennaio 2012 2.24
Sorry. One more question. When I try to invoke... Gerald Rubin 12 gennaio 2012 2.29
http://localhost:8080/tunnel-web/jsonws causes... Kravchenko Dmitry 13 gennaio 2012 5.14
@Gerald http://localhost:8080/api/jsonws is for... Igor Spasić 16 gennaio 2012 5.06
im using LR 6.0.5 . I get a ... s s 17 gennaio 2012 1.58
Please, note that if you're using required... Jussi Kukkonen 2 febbraio 2012 23.26
Can somebody help me with this? Liferay is... R O 11 aprile 2012 3.05
Hi All I have developed a custom spring... Harish Kumar 11 giugno 2012 4.50
Hello, I'm wondering if is possible to have the... Pablo Rendón 18 luglio 2012 8.54
I need call a remote json web service method to... python shi 9 agosto 2012 4.02
Can I pass in the user name and password in the... python shi 9 agosto 2012 4.16
You can use Permission service to check... Nikhil Nishchal 24 ottobre 2012 0.36
Map and List parameters my service method :... python shi 21 novembre 2012 2.28

Nice Wiki....can't wait to have my hands on it..
Inviato il 30/05/11 23.31.
There is a missing part on the registration process. By default, without any further configuration, Liferay does not pick up the classes that has the annotation @JSONWebService in your portlet project. You must configure the "JSON Web Service Servlet" in the web.xml file to get your classes scanned and configured. I tested using revision r82143 of trunk
Inviato il 31/05/11 10.45.
Hi Thiago Leão Moreira, i have a problem with @JSONWebService, eclipse can find it. But i can understand what i had to do to solve this problem.
TK
Inviato il 08/06/11 3.50 in risposta a Thiago Leão Moreira.
Hello,
which Liferay Version do you need to use the "JSONWebService"annotation-Tag? and can what steps are needed to "configure the "JSON Web Service Servlet" in the web.xml file to get your classes scanned and configured" in details?
Thx
Inviato il 07/07/11 1.29.
page has been upgraded to reflect latest code changes. answers for most of your questions are there;)))

this feature is part of 6.1, for portlets you must enable the servlet (as described in the text), for portal it is already on.
Inviato il 28/07/11 5.48.
thx a lot for upgrading the wiki emoticon
Inviato il 09/08/11 2.42 in risposta a Igor Spasić.
@Igor
When you say "this feature is part of 6.1" what are you referring to?

I'm running 6.0 EE SP2, will a ServiceImpl annotated with @JSONWebService in portlet that also declares the "JSON Web Service Servlet" work for me?
Inviato il 06/10/11 14.30 in risposta a Michael W.
Hi Michael, and sorry, I am not quite aware what is actually backported to SP2 - not all functionality has been build at once. Try searching for @JSONWebServices in your portal code;)
Inviato il 11/10/11 3.05 in risposta a Michael Hartman.
page is updated to reflect latest code changes regarding the object parameters.
Inviato il 11/10/11 3.06 in risposta a Igor Spasić.
typically reiventing the wheel!
Inviato il 03/01/12 10.29.
Using 6.1 GA1: I added the <servlet> and <servlet-mapping> xml into my portlet (as is; no changes). I redeployed, etc. I expected that when I browsed to http://localhost:8080/api/jsonws I would see my classes added to the classes (and 901 methods) from the portal. But they DON'T. Should they be? How do I see mine or where did I go wrong? Does <load-on-startup>0</load-on-startup> mean something has to happen before the scanning is done? Please advise. Thanks.
Inviato il 12/01/12 2.24 in risposta a Peter Fox.
Sorry. One more question. When I try to invoke one of the portal's methods (getUser(userId) in this case) I am asked for credentials. Where do I find them? I'm using the Tomcat bundle and don't recall setting credentials. Which ones are they asking for?

Thanks.
Inviato il 12/01/12 2.29 in risposta a Gerald Rubin.
http://localhost:8080/tunnel-web/jsonws causes error 404
Inviato il 13/01/12 5.14.
@Gerald
http://localhost:8080/api/jsonws is for PORTAL services. You must use: localhost:8080/<portlet>/api/jsonws for PORTLET

@Gerald
Credentials are the same you use in portal.

@Dmitry
tunnel-web is obsolete now, Use /api/* instead (document updated).
Inviato il 16/01/12 5.06 in risposta a Kravchenko Dmitry.
im using LR 6.0.5 . I get a
{"exception":"com.liferay.portal.service.http.CountryJSONSerializer"}
when i hit the following URL:
http://<IP_ADDRESS>:8080/tunnel-web/secure/json?serviceClassName=com.liferay­.portal.service.CountryServiceUtil&serviceMethodName=getCountries

However, if I test this by changing the host to liferay.com it works fine:
http://www.liferay.com/tunnel-web/secure/json?serviceClassName=com.liferay.­portal.service.CountryServiceUtil&serviceMethodName=getCountries

what am i doing wrong? is there configuration that i need to do on my liferay install?
Also you mentioned one of your most recent posts that tunnel-web is obsolete, is that not recommended going forward?
Inviato il 17/01/12 1.58 in risposta a Igor Spasić.
Please, note that if you're using required deployment contexts (plugin dependancy) through liferay-plugin-package.properties, you should always use SetPortletClassLoaderServlet to ensure proper class loader initialization for JSONServlet or JSONWebServiceServlet. Here's an example:

<servlet>
<servlet-name>Set Portlet Class Loader Servlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.SetPortletClassLoaderServlet</s­ervlet-class>
<load-on-startup>0</load-on-startup>
</servlet>

<servlet>
<servlet-name>JSON Servlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet</servl­et-class>
<init-param>
<param-name>servlet-class</param-name>
<param-value>com.liferay.portal.servlet.JSONServlet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

I'm using Liferay Portal 6.0 EE SP2.
Inviato il 02/02/12 23.26 in risposta a s s.
Can somebody help me with this? Liferay is asking for credentials when I access standard JSON web service methods, but not for my custom methods (placed in SimpleServiceImpl and SimpleLocalServiceImpl, where Simple is my entity name)? I need to have the custom methods invoked upon successful authentication only. I also used "jsonws.web.service.public.methods= " in portal-ext.properties.
Inviato il 11/04/12 3.05 in risposta a Jussi Kukkonen.
Hi All

I have developed a custom spring portlet and registered the json web services. All the methods defined are listed on page http://localhost:8080/SpringMVC-portlet/api/jsonws as well as added to docroot/js/service.js

but upon calling any of the method getting the following exception -


11:45:54,725 ERROR [JSONWebServiceServiceAction:84] java.lang.ArrayIndexOutOfBoundsException: 1
java.lang.ArrayIndexOutOfBoundsException: 1
at com.liferay.portal.jsonwebservice.JSONWebServiceActionParameters._collectFromPat­h(JSONWebServiceActionParameters.java:165)
at com.liferay.portal.jsonwebservice.JSONWebServiceActionParameters.collectAll(JSON­WebServiceActionParameters.java:57)
at com.liferay.portal.jsonwebservice.JSONWebServiceActionsManagerImpl.getJSONWebSer­viceAction(JSONWebServiceActionsManagerImpl.java:82)
at com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionsManagerUtil.getJSO­NWebServiceAction(JSONWebServiceActionsManagerUtil.java:31)
at com.liferay.portal.jsonwebservice.JSONWebServiceServiceAction.getJSON(JSONWebSer­viceServiceAction.java:71)
at com.liferay.portal.struts.JSONAction.execute(JSONAction.java:60)
at com.liferay.portal.servlet.JSONServlet.service(JSONServlet.java:64)
at com.liferay.portal.jsonwebservice.JSONWebServiceServlet.service(JSONWebServiceSe­rvlet.java:77)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilt­erChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.­java:210)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:72)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:158)
­at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilte­r.java:289)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:55)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:206)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:108)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:158)
­at com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter.processFilter(NtlmPos­tFilter.java:83)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:55)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:206)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:108)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:158)
­at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.ja­va:80)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:55)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:206)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:108)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:158)
­at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.processFilter(V­irtualHostFilter.java:216)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:55)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:206)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:108)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:187)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:95)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.jav­a:738)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFi­lter(InvokerFilterChain.java:206)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:108)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:167)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:95)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:167)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:95)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:116)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDire­ctCallFilter(InvokerFilterChain.java:187)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(In­vokerFilterChain.java:95)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(Invoker­Filter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilt­erChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.­java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:2­24)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:1­69)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.jav­a:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at­ org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118­)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor­.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractPro­tocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)­
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)


Any suggestions would be helpful..
Inviato il 11/06/12 4.50.
Hello,
I'm wondering if is possible to have the same method, let's say accesible with the URL
http://localhost:8080/test-portlet/api/jsonws/dialog/test
and do different thing with different methods dependig if is a Http POST or GET request, I've tryied with different optios but is not working, here the ServiceImple example:

@JSONWebService(value = "/get-test", method = "GET")
public String getTest() {
return "is using GET";
}

@JSONWebService(value = "/get-test", method = "POST")
public String postTest() {
return "is using POST";
}

Thank you!!
Inviato il 18/07/12 8.54.
I need call a remote json web service method to add a file to liferay how to do the PermissionChecker?
when I call /icil-dms-portlet/api/jsonws/dms/add-basci-documen it have the exception:
DMSUtil.getFolderId(): path
DMSUtil.getFolderId(): Portal Exception caught
com.liferay.portal.security.auth.PrincipalException
at com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission.check(­DLFolderPermission.java:42)

And the code:
//login dms and monitor a directory
System.out.println("login dms and monitor a directory upload file to liferay");
HttpHost targetHost = new HttpHost("localhost", 8080, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials("pythonshi", "icilshi"));

// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);

// Add AuthCache to the execution context
BasicHttpContext ctx = new BasicHttpContext();
ctx.setAttribute(ClientContext.AUTH_CACHE, authCache);

//request execute method
HttpPost post = new HttpPost("/icil-dms-portlet/api/jsonws/dms/" +
"add-basci-document?screenName=pythonshi&fileName=/home/python/backup/DMSUtil­.java&title=abc&description=def");

try {
//request
HttpResponse reps = httpclient.execute(targetHost, post, ctx);

//print request result
System.out.println("Request state:\n" + reps.getStatusLine());

System.out.println("\ncall service return result:");
reps.getEntity().writeTo(System.out);

} catch (ClientProtocolException e) {
System.out.println("catch ClientProtocolException:");
e.printStackTrace();
} catch (IOException e) {
System.out.println("catch IOException:");
e.printStackTrace();
}
finally {
//shut down the request
httpclient.getConnectionManager().shutdown();
}
Inviato il 09/08/12 4.02.
Can I pass in the user name and password in the URL to check permission when call remote JSON web service?
Inviato il 09/08/12 4.16.
You can use Permission service to check permission.
you can directly use this service by browser:
http://localhost:8080/api/jsonws?signature=/permission/check-permission-­3-groupId-name-primKey

or found different service list here:
http://localhost:8080/api/jsonws
Inviato il 24/10/12 0.36 in risposta a python shi.
Map and List parameters
my service method :
public String searchFile(String userName, String keywords, ArrayList<String> folderPaths)

I send json string:
{"method":search-file, "params":{"keywords":"log4j.xml","userName":"pythonshi","folderPaths":["/officeH­K/shipment-doc/air/export/August2012","/officeHK/shipment-doc/air/export/October­2012"]}, "id":100, "jsonrpc":"2.0"}
it return:
{"id":100,"error":{"code":-32603,"message":"java.lang.ClassCastException:­ Unable to cast value to type: java.util.ArrayList"},"jsonrpc":"2.0"}

If liferay can't convert the json array to ArrayList auto?
Inviato il 21/11/12 2.28.