我正在开发两个继承类似行为的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;
}