cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Fagerstrom <dani...@nada.kth.se>
Subject Re: ${cocoon.request.contextPath} returns null in 2.2
Date Mon, 29 Jan 2007 18:54:13 GMT
Grzegorz Kossakowski skrev:
> Daniel Fagerstrom napisaƂ(a):
>   
>> Daniel Fagerstrom skrev:
>>     
>>> Grzegorz Kossakowski wrote:
>>>       
>>>> Hello,
>>>>
>>>> I'm hacking now ajax and forms block to get them use of
>>>> servlet-services
>>>> and came across a bug. When you put ${cocoon.request.contextPath} into
>>>> JX template it will always return null (at least while using servlet
>>>> dispatcher). However, ${cocoon.request.requestURI} returns valid value,
>>>> so it must be only contextPath broken somehow. Unfortunately, I have no
>>>> skills to debug this.
>>>> Anyone can at least confirm this? Can you test it without servlet
>>>> dispatcher? (I would do it myself if I knew how)
>>>>   
>>>>         
>>> I have not tested it. But looking at the code the servlet dispatcher
>>> just embeds the request object from the servlet container with a
>>> proxy. And the proxy doesn't affect the contextPath AFAICS, so it
>>> might be that the context path is null in the original request.
>>>
>>> For a servlet service that is called through the servlet protocol,
>>> the contextPath will always be "", which is a bug. Currently the
>>> request object of the calling servlet service is not available in the
>>> servlet source, so there is no easy fix. I plan to refactor the call
>>> stack and make it available there.
>>>
>>> In the servlet architecture we have:
>>>
>>> requestURI = contextPath + servletPath + pathInfo
>>>
>>> As the servlet service architecture creates an extra level of paths
>>> relative to the servlet architecture there are several possibilities
>>> where to add the mountPath.  I solved it in the following way: the
>>> dispatcher servlet will look for the mountPath that is the longest
>>> prefix in the incoming pathInfo. It will then create a new
>>> servletPath and pathInfo for the called servlet service:
>>>
>>> newServletPath = servletPath + mountPath
>>> newPathInfo = pathInfo.substring(mountPath.length())
>>>
>>> So as you can see the contextPath will be the same as for all servlet
>>> services.
>>>       
>> Taking a look at your patches in JIRA I see that you have replaced
>>  {request:contextPath}/_cocoon/resources
>> with
>>  /blocks-test/cocoon-forms-impl/resources
>>
>> Now the original pattern is actually faulty (even if it seem to be
>> used everywhere in the samples), it should have been
>>  {request:contextPath}{request:servletPath}/_cocoon/resources
>> and
>>  {request:contextPath}{request:servletPath}/resources
>> in your refactored code.
>>
>> The only reason that the samples work is that the web.xml in
>> cocoon-webapp mounts the sitemap servlet at "/*" which gives
>> servletPath="", but there is no reason to constrain the use of the
>> sitemap servlet to be used only with an empty servlet path. A servlet
>> is supposed to be mountable wherever the user want it.
>>
>> Using the servlet service fw, sitemap servlets will be mounted at
>> other paths and the servletPath must be taken into account.
>>     
> Thanks for explanation. However, your proposed solution will not work.
> In cocoon-ajax-sample we have:
> <script type="text/javascript"
> src="/blocks-test/cocoon-ajax-impl/resources/dojo/dojo.js"/>
> Now if it is replaced by:
> <script type="text/javascript"
> src="${cocoon.request.contextPath}${cocoon.request.servletPath}/resources
> /resources/dojo/dojo.js"/>
> It would be resolved into:
> <script type="text/javascript"
> src="/blocks-test/cocoon-ajax-sample/resources/dojo/dojo.js"/>
>
> So in short, all we want is '/blocks-test' part, the rest depends on
> which block's resources we link to. How get this part?
>   
You don't get that part, which show that there is a problem with my 
design. I probably mounted the dispatcher servlet at "/*" while 
developing the stuff :/ Thinking a little bit more about it, it would 
probably better to let the servlet path of the dispatcher servlet go to 
the context path when calling the servlet services. Then we would get:

newContextPath = contextPath + servletPath
newServletPath = mountPath
newPathInfo = pathInfo.substring(mountPath.length())

where servletPath above is the servletPath of the dispatcher servlet in 
the web.xml. Looking at it this mapping looks much more natural than the 
original one. But there might have been some god reason that I choose 
the original design that I have forgotten. If no one finds any problem 
with the new proposal we could switch to that.

To get the mountPath, it is better to use the blockPath module e.g. 
{block-path:ajax} (assuming that the cocoon-ajax-impl service servlet is 
connected at the name ajax in the Spring config). You can also use the 
service protocol inside the pipeline:

<script type="text/javascript"
src="servlet:ajax://resources/dojo/dojo.js"/>

and end the pipeline with a link rewriter transformer that use the block 
path module to get the path right.

The link rewriter transformer can probably be configured to add the 
prefix "/blocks-test" as well 
http://cocoon.apache.org/2.1/apidocs/org/apache/cocoon/transformation/LinkRewriterTransformer.html.

/Daniel


Mime
View raw message