SpringMVC:我可以将JSTLImport标签URL指向相对于当前控制器的端点吗



我正在开发两个继承类似行为的JSP。我试图通过使用一个基本控制器和jsp来实现这一点,该控制器和jsp提供基本行为,并使用<c:import />标记来访问在基本控制器的子类中定义的端点,以获得更多内容。我在定义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";
    }
}

在本例中,它不起作用,因为导入的URL引用/customForm,但它需要引用/myController/customForm/myController2/customForm,这取决于访问哪个控制器以提供初始页面(/myController/main/myController2/main)。

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

我曾想过在/main端点中获取请求路径,提取控制器的映射,然后将其添加为模型属性,然后我可以在jsp上访问该属性来构建URL,但我觉得必须有更好的方法来实现这一点。有人有什么想法吗?

我相信你可以简单地使用18.3瓷砖来实现你想要的目标,如所述

您的配置如下//baseform.jsp注意瓷砖占位符

 <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-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>

根据我在您的问题中看到的内容,您可以将控制器映射捕获为路径变量,并在此基础上解析视图。例如,在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;
}

最新更新