Spring MVC:我可以在相对于当前控制器的端点上指向JSTL Import标记URL

时间:2015-02-13 11:41:42

标签: java jsp spring-mvc servlets jstl

我正在开发一些继承类似行为的JSP。我试图通过一个基本控制器和jsp提供基本行为来实现这一点,并使用<c:import />标签来命中在基本控制器的子类中定义的端点以获得更多内容。我在定义导入标记的url以从子类控制器中找到正确的端点时遇到问题。

基本控制器:

@Controller
public abstract class AbstractController {

    @RequestMapping(value = "/main")
    public String getForm() {
        return "MyForm";
    }

    @RequestMapping(value = "/customForm")
    public abstract String getCustomForm();
}

MyForm.jsp

<c:import url="/customForm" />

我的实施:

@RequestMapping(value = "/myController")
public class MyController extends AbstractController {

    @Override
    public String getCustomForm() {
        return "MyCustomForm";
    }

}

另一种实现可能如下:

@RequestMapping(value = "/myController2")
public class MyController2 extends AbstractController {

    @Override
    public String getCustomForm() {
        return "MyCustomForm2";
    }

}

在此示例中,它不起作用,因为导入的引用引用/customForm,但它需要引用/myController/customForm/myController2/customForm,具体取决于访问哪个控制器以提供首页(/myController/main/myController2/main)。

有什么办法可以使用标准的<c:import />代码来实现这种行为吗?

我考虑过在/main端点获取请求路径并提取控制器的映射,然后将其添加为模型属性,然后我可以在jsp上访问以构建URL,但我觉得必须有这样做的更好方法。有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

我相信您可以通过18.3 Tiles as explained here

轻松实现您的目标

您的配置如下所示     //baseform.jsp注意tile占位符

 <form:form id="add_update_form" modelAttribute="mymodel" action="${ctx}/views/sections/action" method="post">
        <tiles:insertAttribute name="header" />

         <tiles:insertAttribute name="content" />

        <tiles:insertAttribute name="footer" />

    </form:form>

你的Tiles定义看起来像

//tiles-layout.xml notice the contents of the placeholders defined above

<tiles-definitions>
    <!-- Abstract root definition -->
     <definition name="baseFrom" template="/WEB-INF/jsp/base/tiles/base.jsp">
        <put-attribute name="header" value="/WEB-INF/jsp/base/tiles/formheader.jsp"/>
        <put-attribute name="content" value=""/>
        <put-attribute name="footer" value="/WEB-INF/jsp/base/tiles/formfooter.jsp"/>
    </definition>

     <definition name="main" extends="baseFrom">
         <put-attribute name="content" value="/WEB-INF/views/sections/main.jsp"/>
    </definition> 
     <definition name="section1" extends="baseFrom">
         <put-attribute name="group" cascade="true" value="Terms"/>
         <put-attribute name="content" value="/WEB-INF/views/sections/section1Form.jsp"/>
    </definition>

    <definition name="section2" extends="baseFrom">
         <put-attribute name="group" cascade="true" value="Terms"/>
         <put-attribute name="content" value="/WEB-INF/views/sections/section2Form.jsp"/>
    </definition>

    <definition name="section3" extends="baseFrom">
         <put-attribute name="content" value="/WEB-INF/views/sections/section2Form.jsp"/>
    </definition>

</tiles-definitions>

并且您的控制器看起来像

@Controller
public class Controller {

    @RequestMapping(value = "/main")
    public String getForm() {
        return "main";//tiles definition
    }

    @RequestMapping(value = "/customForm1")
    public  String getCustomForm(){
     return "section1"; // tiles definition
    }

    @RequestMapping(value = "/customForm2")
    public  String getCustomForm(){
     return "section2";
    }
}

现在你的开发人员不需要扩展控制器,他们只需要添加一个新的tile定义,扩展baseForm定义并提供新的jsp部分

in //tiles-layout.xml,&  put contents of the placeholder

    <definition name="newSection" extends="baseFrom">
             <put-attribute name="content" value="/WEB-INF/views/sections/newSectionForm.jsp"/>
        </definition>

答案 1 :(得分:0)

根据我在您的问题中看到的,您可以将控制器映射捕获为路径变量,并基于此解析您的视图。例如,在 AbstractController

中添加以下映射
@RequestMapping(value = "/{controller}/customForm")
public String getCustomForm(@PathVariable String controller) {
    String returnValue = null;
    if (controller.equals("myController")) {
        returnValue = "MyCustomForm";
    } else if (controller.equals("MyCustomForm2")) {
        returnValue = "MyCustomForm2";
    }
    return returnValue;
}