java spring mvc 转发到 jsp
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5032558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
spring mvc forward to jsp
提问by jerluc
I currently have my web.xml configured to catch 404s and send them to my spring controller which will perform a search given the original URL request.
我目前将 web.xml 配置为捕获 404 并将它们发送到我的 spring 控制器,该控制器将根据原始 URL 请求执行搜索。
The functionality is all there as far as the catch and search go, however the trouble begins to arise when I try to return a view.
就捕获和搜索而言,功能就在那里,但是当我尝试返回视图时,麻烦就开始出现了。
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="jsp" value="text/html" />
</map>
</property>
<property name="defaultContentType" value="application/json" />
<property name="favorPathExtension" value="true" />
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value="" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingHymansonJsonView" />
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
This is a snippet from my MVC config file.
这是我的 MVC 配置文件中的一个片段。
The problem lies in resolving the view's path to the /WEB-INF/jsp/
directory. Using a logger in my JBoss setup, I can see that when I test this search controller by going to a non-existent page, the following occurs:
问题在于解析视图的/WEB-INF/jsp/
目录路径。在我的 JBoss 设置中使用记录器,我可以看到当我通过转到一个不存在的页面来测试这个搜索控制器时,会发生以下情况:
Server can't find the request
Request is sent to 404 error page (in this case my search controller)
Search controller performs search
Search controller returns view name (for this illustration, we'll assume
test.jsp
is returned)Based off of server logger, I can see that
org.springframework.web.servlet.view.JstlView
is initialized once my search controller returns the view name (so I can assume it is being picked up correctly by theInternalResourceViewResolver
)Server attempts to return content to browser resulting in a 404!
服务器找不到请求
请求被发送到 404 错误页面(在这种情况下我的搜索控制器)
搜索控制器执行搜索
搜索控制器返回视图名称(对于本例,我们假设
test.jsp
返回)基于服务器记录器,我可以看到,
org.springframework.web.servlet.view.JstlView
一旦我的搜索控制器返回视图名称,它就会被初始化(所以我可以假设它被正确地拾取InternalResourceViewResolver
)服务器尝试将内容返回到浏览器导致 404!
A couple things confuse me about this:
有几件事让我对此感到困惑:
I'm not 100% sure why this isn't resolving when
test.jsp
clearly exists under the/WEB-INF/jsp/
directory.Even if there was some other problem, why would this result in a 404? Shouldn't a 404 error page that results in another 404 theoretically create an infinite loop?
我不是 100% 确定为什么当目录
test.jsp
下明确存在时这不能解决/WEB-INF/jsp/
。即使有其他问题,为什么会导致 404?理论上导致另一个 404 的 404 错误页面不应该创建无限循环吗?
Thanks for any help or pointers!
感谢您的帮助或指点!
Controller class [incomplete]:
控制器类[不完整]:
@Controller
public class SiteMapController {
//--------------------------------------------------------------------------------------
@Autowired(required=true)
private SearchService search;
@Autowired(required=true)
private CatalogService catalog;
//--------------------------------------------------------------------------------------
@RequestMapping(value = "/sitemap", method = RequestMethod.GET)
public String sitemap (HttpServletRequest request, HttpServletResponse response) {
String forwardPath = "";
try {
long startTime = System.nanoTime() / 1000000;
String pathQuery = (String) request.getAttribute("javax.servlet.error.request_uri");
Scanner pathScanner = new Scanner(pathQuery).useDelimiter("\/");
String context = pathScanner.next();
List<ProductLightDTO> results = new ArrayList<ProductLightDTO>();
StringBuilder query = new StringBuilder();
String currentValue;
while (pathScanner.hasNext()) {
currentValue = pathScanner.next().toLowerCase();
System.out.println(currentValue);
if (query.length() > 0)
query.append(" AND ");
if (currentValue.contains("-")) {
query.append("\"");
query.append(currentValue.replace("-", " "));
query.append("\"");
}
else {
query.append(currentValue + "*");
}
}
//results.addAll(this.doSearch(query.toString()));
System.out.println("Request: " + pathQuery);
System.out.println("Built Query:" + query.toString());
//System.out.println("Result size: " + results.size());
long totalTime = (System.nanoTime() / 1000000) - startTime;
System.out.println("Total TTP: " + totalTime + "ms");
if (results == null || results.size() == 0) {
forwardPath = "home.jsp";
}
else if (results.size() == 1) {
forwardPath = "product.jsp";
}
else {
forwardPath = "category.jsp";
}
}
catch (Exception ex) {
System.err.println(ex);
}
System.out.println("Returning view: " + forwardPath);
return forwardPath;
}
}
回答by jerluc
1 . I'm not 100% sure why this isn't resolving when test.jsp clearly exists under the /WEB-INF/jsp/ directory.
1 . 当 test.jsp 明确存在于 /WEB-INF/jsp/ 目录下时,我不是 100% 确定为什么这不能解决。
This is because you did configure your view resolver with suffix = ""
so the file must be named test
(no extension).
这是因为您确实配置了视图解析器,suffix = ""
因此必须命名文件test
(无扩展名)。
2 . Even if there was some other problem, why would this result in a 404? Shouldn't a 404 error page that results in another 404 theoretically create an infinite loop?
2 . 即使有其他问题,为什么会导致 404?理论上导致另一个 404 的 404 错误页面不应该创建无限循环吗?
I'm pretty sure this's the result of some protection against the infinite redirect loop in spring MVC.
我很确定这是针对 spring MVC 中的无限重定向循环的一些保护的结果。
Note:in controllers, spring expect a view name as a result so test
not test.jsp
(or better, use ModelAndView
)
注意:在控制器中,spring 期望一个视图名称作为结果所以test
不是test.jsp
(或者更好,使用ModelAndView
)
回答by gigadot
I am posting this as answer because it is too long but it is probably not an answer.
我将此作为答案发布,因为它太长了,但它可能不是答案。
http://localhost:8080/webapp/servlet-mapping-url/controller-mapping/method-mapping
if your controller's method which handles the request does not return a view name string or a view object or write directly to output stream, spring dispatcher should resolve the view name to /WEB-INF/jsp/controller-mapping/method-mapping.jsp
如果处理请求的控制器方法没有返回视图名称字符串或视图对象或直接写入输出流,则 spring 调度程序应将视图名称解析为 /WEB-INF/jsp/controller-mapping/method-mapping.jsp
This means the jsp must be under a folder, named /WEB-INF/jsp/controller-mapping/
. However, if a view name or view object is return by the controller method, spring dispatcher will uses that instead.
这意味着 jsp 必须位于名为 /WEB-INF/jsp/controller-mapping/
. 但是,如果控制器方法返回视图名称或视图对象,则 spring 调度程序将使用它。
Ther are other many possible mapping combination but this is the most common one. If you could show your controller class, it will be easier.
还有其他许多可能的映射组合,但这是最常见的一种。如果你能展示你的控制器类,它会更容易。
Update
更新
If you are using DefaultAnnotationHandlerMapping
, you should always annotated your class with @RequestMapping(value = "/mapping-string")
. Otherwise spring dispatcher will try to pick it up when nothing else is matched.
如果您使用的是DefaultAnnotationHandlerMapping
,则应始终使用@RequestMapping(value = "/mapping-string")
. 否则 spring 调度程序将在没有其他匹配项时尝试将其捡起。
Since the controller is mapped, you will have to change the method mapping to value = {"", "/"}
由于控制器已映射,因此您必须将方法映射更改为 value = {"", "/"}
For the returning view name, you don't need to put .jsp
.
对于返回的视图名称,您不需要将.jsp
.
If the returning view name is home
then the spring dispatcher will resolve to /WEB-INF/jsp/home.jsp
如果返回的视图名称是home
那么 spring 调度程序将解析为/WEB-INF/jsp/home.jsp
If the returning view name is path/home
then the spring dispatcher will resolve to /WEB-INF/jsp/path/home.jsp
如果返回的视图名称是path/home
那么 spring 调度程序将解析为/WEB-INF/jsp/path/home.jsp
P.S. You used a word forwardPath but it isn't really a forward. It is just a view name.
PS 您使用了一个词 forwardPath 但它不是真正的转发。它只是一个视图名称。
@Controller
@RequestMapping(value = "/sitemap")
public class SiteMapController {
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public String sitemap (HttpServletRequest request, HttpServletResponse response) {
...
if (results == null || results.size() == 0) {
forwardPath = "home";
}
else if (results.size() == 1) {
forwardPath = "product";
}
else {
forwardPath = "category";
}
...
return forwardPath;
}
}
回答by DzianisH
Try to set order for your ViewResolver. For Example:
尝试为您的 ViewResolver 设置顺序。例如:
@Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setOrder(1);
return resolver;
}