我正在开发一些继承类似行为的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,但我觉得必须有这样做的更好方法。有没有人有任何想法?
答案 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;
}