Skip to content

Commit

Permalink
Use request URI to resolve the view name if previous resolver doesn't…
Browse files Browse the repository at this point in the history
… found a view

Fixes grails/grails-core#10582
  • Loading branch information
ilopmar committed Feb 22, 2018
1 parent 37e36eb commit 3930166
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import groovy.transform.CompileStatic
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.springframework.web.servlet.View
import org.springframework.web.servlet.ViewResolver

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
* A UrlBasedViewResolver for ResolvableGroovyTemplateEngine
*
Expand All @@ -22,9 +26,9 @@ class GenericGroovyTemplateViewResolver implements ViewResolver {
@Override
View resolveViewName(String viewName, Locale locale) throws Exception {
def webRequest = GrailsWebRequest.lookup()
if(webRequest != null) {
if (webRequest != null) {
def currentRequest = webRequest?.currentRequest
if(viewName.startsWith('/')) {
if (viewName.startsWith('/')) {
def controller = webRequest.controllerClass
View view
if (controller && controller.namespace) {
Expand All @@ -37,24 +41,32 @@ class GenericGroovyTemplateViewResolver implements ViewResolver {
view = smartViewResolver.resolveView(viewName, currentRequest, webRequest.response)
}
return view
}
else {

} else {
def controllerUri = webRequest?.attributes?.getControllerUri(currentRequest)
if(controllerUri) {
return smartViewResolver.resolveView(
"${controllerUri}/$viewName",
currentRequest,
webRequest.currentResponse
)
View view = this.resolveViewWithController(controllerUri, viewName, webRequest)

if (!view) {
controllerUri = currentRequest?.requestURI
view = this.resolveViewWithController(controllerUri, viewName, webRequest)
}
else {

if (view) {
return view
} else {
return smartViewResolver.resolveView(viewName, currentRequest, webRequest.response)
}
}
}
else {
} else {
smartViewResolver.resolveView(viewName, locale)
}
}

private View resolveViewWithController(String controllerUri, String viewName, GrailsWebRequest webRequest) {
HttpServletRequest currentRequest = webRequest?.currentRequest
HttpServletResponse currentResponse = webRequest?.currentResponse

if (controllerUri) {
return smartViewResolver.resolveView("${controllerUri}/$viewName", currentRequest, currentResponse)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ package grails.plugin.json.view
import grails.plugin.json.view.mvc.JsonViewResolver
import grails.views.ResolvableGroovyTemplateEngine
import grails.views.TemplateResolver
import grails.views.ViewUriResolver
import grails.views.WritableScriptTemplate
import grails.views.api.GrailsView
import grails.views.mvc.GenericGroovyTemplateView
import grails.views.mvc.GenericGroovyTemplateViewResolver
import grails.web.http.HttpHeaders
import grails.web.mime.MimeType
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.servlet.View
import org.springframework.web.servlet.view.AbstractUrlBasedView
import spock.lang.Issue
import spock.lang.Specification

import javax.servlet.http.HttpServletRequest
Expand Down Expand Up @@ -148,6 +145,43 @@ class JsonViewTemplateResolverSpec extends Specification {
1 * templateResolver.resolveTemplate('/test/bar_en_html.gson')

cleanup:
RequestContextHolder.setRequestAttributes(null)
RequestContextHolder.setRequestAttributes(null)
}

@Issue('https://github.com/grails/grails-core/issues/10582')
void 'Test that the template resolver works for a Request URI'() {
given: 'a viewResolver with a mock template resolver'
def smartResolver = new JsonViewResolver()
def viewResolver = new GenericGroovyTemplateViewResolver(smartResolver)

def webRequest = Mock(GrailsWebRequest)

and: 'the default controller URI'
def applicationAttributes = Mock(GrailsApplicationAttributes)
applicationAttributes.getControllerUri(_) >> "/test"
webRequest.getAttributes() >> applicationAttributes

and: 'the actual URI because of a redirect'
webRequest.getCurrentRequest() >> new MockHttpServletRequest("", "/foo")
RequestContextHolder.setRequestAttributes(webRequest)
def templateResolver = Mock(TemplateResolver)

smartResolver.templateEngine.templateResolver = templateResolver

when: 'we resolve a template'
GenericGroovyTemplateView view = (GenericGroovyTemplateView)viewResolver.resolveViewName("bar", Locale.ENGLISH)

then: 'the view is not null'
1 * templateResolver.resolveTemplateClass('/foo/bar.gson')
1 * templateResolver.resolveTemplateClass('/foo/bar_en.gson')
1 * templateResolver.resolveTemplateClass('/foo/bar_html.gson')
1 * templateResolver.resolveTemplateClass('/foo/bar_en_html.gson')
1 * templateResolver.resolveTemplate('/foo/bar.gson')
1 * templateResolver.resolveTemplate('/foo/bar_en.gson')
1 * templateResolver.resolveTemplate('/foo/bar_html.gson')
1 * templateResolver.resolveTemplate('/foo/bar_en_html.gson')

cleanup:
RequestContextHolder.setRequestAttributes(null)
}
}

0 comments on commit 3930166

Please sign in to comment.