问题
I have an issue with integrating the spring batch admin console into my application.
The good news is that when i go to http://mymachine.com:8080/ReportingManager/batch/configuration I can get to the admin console.
But when I go to http://mymachine.com:8080/ReportingManager/batch/job-configuration i get a 404 and an error saying that /batch/jobs can't be found.
I've just gone through the exercise of comparing the difference in output of org.springframework.web logs between my application logs and the spring-batch-admin-sample application which I know is working.
After looking at the logs it looks like the URL mappings can be found for the spring batch admin console but the DispatcherServlet is trying to use InternalResourceViewResolver instead of the FreeMarkerViewResolver
My application logs below show the wrong ViewResolver is being used for /ReportingManager/batch/jobs...
2014-05-27 20:16:22,770 DEBUG [DispatcherServlet] - DispatcherServlet with name 'Batch Servlet' processing GET request for [/ReportingManager/batch/jobs]
2014-05-27 20:16:22,770 DEBUG [RequestMappingHandlerMapping] - Looking up handler method for path /jobs
2014-05-27 20:16:22,770 DEBUG [RequestMappingHandlerMapping] - Returning handler method [public void org.springframework.batch.admin.web.JobController.jobs(org.springframework.ui.ModelMap,int,int)]
2014-05-27 20:16:22,770 DEBUG [DispatcherServlet] - Last-Modified value for [/ReportingManager/batch/jobs] is: -1
2014-05-27 20:16:23,598 DEBUG [DispatcherServlet] - Rendering view [org.springframework.web.servlet.view.JstlView: name 'jobs'; URL [/WEB-INF/pages/jobs.jsp]] in DispatcherServlet with name 'Batch Servlet'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Added model object 'endJob' of type [java.lang.Integer] to request in view with name 'jobs'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Added model object 'jobs' of type [java.util.ArrayList] to request in view with name 'jobs'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Added model object 'startJob' of type [java.lang.Integer] to request in view with name 'jobs'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Added model object 'totalJobs' of type [java.lang.Integer] to request in view with name 'jobs'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Added model object 'jobName' of type [java.lang.String] to request in view with name 'jobs'
2014-05-27 20:16:23,598 DEBUG [JstlView] - Forwarding to resource [/WEB-INF/pages/jobs.jsp] in InternalResourceView 'jobs'
2014-05-27 20:16:23,598 DEBUG [DispatcherServlet] - Successfully completed request
Whereas when I look at the longs for the spring-batch-admin-sample I can see that /spring_admin_console/jobs is using AjaxFreeMarkerView...
[5/27/14 19:57:13:962 EST] 00000023 SystemOut O 19:57:13,950 DEBUG WebContainer : 0 servlet.DispatcherServlet:693 - DispatcherServlet with name 'Batch Servlet' processing GET request for [/s
pring_admin_console/jobs]
[5/27/14 19:57:13:978 EST] 00000023 SystemOut O 19:57:13,965 DEBUG WebContainer : 0 annotation.DefaultAnnotationHandlerMapping:221 - Mapping [/jobs] to HandlerExecutionChain with handler [or
g.springframework.batch.admin.web.JobController@52e052e0] and 3 interceptors
[5/27/14 19:57:14:000 EST] 00000023 SystemOut O 19:57:13,988 DEBUG WebContainer : 0 servlet.DispatcherServlet:769 - Last-Modified value for [/spring_admin_console/jobs] is: -1
[5/27/14 19:57:14:045 EST] 00000023 SystemOut O 19:57:14,031 DEBUG WebContainer : 0 support.HandlerMethodInvoker:155 - Invoking model attribute method: public java.lang.String org.spring
framework.batch.admin.web.JobController.getJobName(javax.servlet.http.HttpServletRequest)
[5/27/14 19:57:14:091 EST] 00000023 SystemOut O 19:57:14,078 DEBUG WebContainer : 0 support.HandlerMethodInvoker:173 - Invoking request handler method: public void org.springframework.batch.admin.web.JobController.jobs(org.springframework.ui.ModelMap,int,int)
[5/27/14 19:57:14:125 EST] 00000023 SystemOut O 19:57:14,113 DEBUG WebContainer : 0 servlet.DispatcherServlet:1045 - Rendering view org.springframework.batch.admin.web.freemarker.AjaxFreeMarkerView: name 'jobs'; URL [/layouts/html/standard.ftl]] in DispatcherServlet with name 'Batch Servlet'
[5/27/14 19:57:14:144 EST] 00000023 SystemOut O 19:57:14,130 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'springMacroRequestContext' of type [org.springframework.web.servlet.support.RequestContext] to request in view with name 'jobs'
[5/27/14 19:57:14:158 EST] 00000023 SystemOut O 19:57:14,144 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'startJob' of type [java.lang.Integer] to request i
n view with name 'jobs'
[5/27/14 19:57:14:172 EST] 00000023 SystemOut O 19:57:14,159 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'totalJobs' of type [java.lang.Integer] to request
in view with name 'jobs'
[5/27/14 19:57:14:186 EST] 00000023 SystemOut O 19:57:14,172 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'servletPath' of type [java.lang.String] to request
in view with name 'jobs'
[5/27/14 19:57:14:200 EST] 00000023 SystemOut O 19:57:14,186 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'jobName' of type [java.lang.String] to request in
view with name 'jobs'
[5/27/14 19:57:14:214 EST] 00000023 SystemOut O 19:57:14,200 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'jobs' of type [java.util.ArrayList] to request in
view with name 'jobs'
[5/27/14 19:57:14:228 EST] 00000023 SystemOut O 19:57:14,214 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'titleText' of type [java.lang.String] to request i
n view with name 'jobs'
[5/27/14 19:57:14:242 EST] 00000023 SystemOut O 19:57:14,228 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'titleCode' of type [java.lang.String] to request i
n view with name 'jobs'
[5/27/14 19:57:14:255 EST] 00000023 SystemOut O 19:57:14,242 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'endJob' of type [java.lang.Integer] to request in
view with name 'jobs'
[5/27/14 19:57:14:269 EST] 00000023 SystemOut O 19:57:14,256 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:328 - Added model object 'body' of type [java.lang.String] to request in vie
w with name 'jobs'
[5/27/14 19:57:14:287 EST] 00000023 SystemOut O 19:57:14,274 DEBUG WebContainer : 0 freemarker.AjaxFreeMarkerView:279 - Rendering FreeMarker template [/layouts/html/standard.ftl] in FreeMark
erView 'jobs'
[5/27/14 19:57:14:909 EST] 00000023 SystemOut O 19:57:14,895 DEBUG WebContainer : 0 servlet.DispatcherServlet:674 - Successfully completed request
I've spent a while trying to find out what is happening and am not sure. I suspect maybe I am doing something wrong in my web.xml. Maybe relating to the order of the servlets.
I am going to post an excerpt from my web.xml in the hopes that someone will see something I am doing wrong.
Thanks in advance for having a look at this for me.
I've put my web.xml here.
http://pastebin.com/eBkHMe8g
回答1:
In your web project make sure you have this folder structure: WEB-INF\classes\META-INF\spring\batch\override
. And under this folder create a new .xml file. Name it whatever name you want. The content of the file should be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="resourceService" class="org.springframework.batch.admin.web.resources.DefaultResourceService">
<property name="servletPath" value="/batch" />
</bean>
</beans>
The value for the servletPath
needs to match your servlet-mapping
in your web.xml
. I used /batch
because this is what you have in yours.
More about this here. Also, it does help to have a look at the Spring Batch Admin source code. In that resources-context.xml
you can see that a certain SPeL expression is used for various servletPath
resources: <prop key="servletPath">#{resourceService.servletPath}</prop>
. You need to search for the bean called resourceService
, have a look at its source code and from there you can establish what property to change for DefaultResourceService
in your custom .xml file.
LATER EDIT: As a general suggestion, your mvc-dispatcher
DispatcherServlet is picking up automatically and by default the file located at /WEB-INF/mvc-dispatcher-servlet.xml
. You'll have the beans under mvc-dispatcher-servlet.xml
being picked up and loaded twice in two different app contexts because you have this file specified as one of the contextConfigLocation
values. There is a hierarchy of contexts there, root one (defined by contextConfigLocation
) being the parent. The idea is to place beans that are non-web (or that are to be used by web) in the root context and the web to be able to "use" these beans. Other way around doesn't quite make sense, because a DAO or Service class doesn't need access to web.
来源:https://stackoverflow.com/questions/23880396/batch-admin-console-dispatcherservlet-using-internalresourceviewresolver-inste