当组件作为会话作用域时,无法将Spring控制器作为请求范围

我正在尝试按照本网站上的指南来正确地将我的bean用于Spring网络应用程序:

http://richardchesterwood.blogspot.com/2011/03/using-sessions-in-spring-mvc-including.html

我正在尝试遵循方法3,这基本上意味着我想将我的组件类作为会话范围,因此我必须根据请求调整我的控制器类的范围。 我将控制器放入我的JSP页面,以便可以使用它。

但是,当我尝试这样做时,我的webapp存在构建问题,当我尝试访问网页时,它给出了503 service_unavailable错误。

构建错误是:

严重:上下文初始化失败org.springframework.beans.factory.BeanCreationException:创建名为’org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0’的bean时出错:bean的初始化失败; 嵌套exception是java.lang.IllegalStateException:无法将处理程序’currentWeekController’映射到URL路径[/ TimeTracking]:已经映射了处理程序’scopedTarget.currentWeekController’。

这是相关的类和jsp页面。 如果您还有其他需要,请随便询问!

CurrentWeekController控制器类:

package controllers; import javax.servlet.http.HttpServletRequest; import models.CurrentWeek; import models.ModelMap; import models.User; import org.joda.time.MutableDateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * this is the controller for current week, it lets you change the current week * and get values from the current week * * @author CorayThan * */ @Controller @Scope("Request") public class CurrentWeekController { private static final int MONDAY = 1; private static final int TUESDAY = 2; private static final int WEDNESDAY = 3; private static final int THURSDAY = 4; private static final int FRIDAY = 5; private static final int SATURDAY = 6; private static final int SUNDAY = 7; @Autowired private User user; @Autowired private CurrentWeek currentWeek; @Autowired private ModelMap hashmap; /** * @return the user */ public User getUser() { return user; } /** * @param user * the user to set */ public void setUser(User user) { this.user = user; } /** * @return the currentWeek checks to make sure the week isn't null and its * monday isn't null and fixes them if they are */ public CurrentWeek getCurrentWeek() { if (currentWeek == null) { this.createNewCurrentWeek(); } if (currentWeek.getMonday() == null) { this.createCurrentWeek(MutableDateTime.now()); } return currentWeek; } /** * @param currentWeek * the currentWeek to set */ public void setCurrentWeek(CurrentWeek currentWeek) { this.currentWeek = currentWeek; } /** * @return the hashmap */ public ModelMap getHashmap() { return hashmap; } /** * @param hashmap * the hashmap to set */ public void setHashmap(ModelMap hashmap) { this.hashmap = hashmap; } /** * no arg constructor */ public CurrentWeekController() { } /** * this is a post method called when a button is clicked on the time * tracking jsp page. It reloads the page with a different week * * @param pageWeek * @param request * @return */ @RequestMapping(value = "TimeTracking") public ModelAndView changeTheWeek(HttpServletRequest request) { String whichWayWeek = request.getParameter("changeWeek"); if ("Previous Week".equals(whichWayWeek)) { this.subtractOneWeek(); } if ("Next Week".equals(whichWayWeek)) { this.addOneWeek(); } return new ModelAndView("redirect:/jsp-pages/TimeTracking.jsp", hashmap.makeHashMap()); } /** * This creates a current week object by setting that week's monday to the * proper monday for that week using whatever date you give it * * * @param calendar * @return */ public CurrentWeek createCurrentWeek(MutableDateTime theCurrentDate) { int day = checkForNull(theCurrentDate); switch (day) { case SUNDAY: theCurrentDate.addDays(-6); currentWeek.setMonday(theCurrentDate); break; case SATURDAY: theCurrentDate.addDays(-5); currentWeek.setMonday(theCurrentDate); break; case FRIDAY: theCurrentDate.addDays(-4); currentWeek.setMonday(theCurrentDate); break; case THURSDAY: theCurrentDate.addDays(-3); currentWeek.setMonday(theCurrentDate); break; case WEDNESDAY: theCurrentDate.addDays(-2); currentWeek.setMonday(theCurrentDate); break; case TUESDAY: theCurrentDate.addDays(-1); currentWeek.setMonday(theCurrentDate); break; case MONDAY: currentWeek.setMonday(theCurrentDate); break; default: this.setCurrentWeek(null); break; } return this.getCurrentWeek(); } /** * @param theCurrentDate * @return * makes sure the current date isn't null, and returns an int equal to * the day of the week it is in joda time */ private int checkForNull(MutableDateTime theCurrentDate) { int day = 0; if (theCurrentDate != null) { day = theCurrentDate.getDayOfWeek(); } return day; } /** * makes a new current week set to the real current week * * @return */ public CurrentWeek createNewCurrentWeek() { MutableDateTime dateTime = MutableDateTime.now(); CurrentWeek currentWeek = new CurrentWeek(); this.setCurrentWeek(currentWeek); return createCurrentWeek(dateTime); } /** * subtracts one week from a currentweek * * * @return */ public void subtractOneWeek() { MutableDateTime newMonday = (MutableDateTime) this.getCurrentWeek() .getMonday().clone(); newMonday.addDays(-7); this.setCurrentWeek(createCurrentWeek(newMonday)); } /** * adds one week to a currentweek * * @param currentWeek * @return */ public void addOneWeek() { MutableDateTime newMonday = (MutableDateTime) this.getCurrentWeek() .getMonday().clone(); newMonday.addDays(7); this.setCurrentWeek(createCurrentWeek(newMonday)); } /** * TODO: make this method into a method that accepts a current week and * checks if you can add a week to it without going entirely into the future * * @param currentWeek * @return */ public CurrentWeek checkIfCurrentWeekIsEntirelyInFuture() { return this.getCurrentWeek(); } /** * returns the first day of the week as a formatted date time * * @return */ public String firstDayOfThisWeek() { MutableDateTime firstDay = this.getCurrentWeek().getSunday(); DateTimeFormatter dateFormatter = DateTimeFormat .forPattern("MM/dd/yyyy"); return dateFormatter.print(firstDay); } /** * returns the last day of this week as a formatted date time * * @return */ public String lastDayOfThisWeek() { MutableDateTime lastDay = this.getCurrentWeek().getSaturday(); DateTimeFormatter dateFormatter = DateTimeFormat .forPattern("MM/dd/yyyy"); return dateFormatter.print(lastDay); } } 

这是CurrentWeek组件类。

 package models; import org.joda.time.MutableDateTime; import org.springframework.stereotype.Component; /** * this is a class that holds the current week for views * * @author CorayThan * */ @Component // @Scope ("Session") public class CurrentWeek { private MutableDateTime monday; /** * default constructor */ public CurrentWeek() { } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getSunday() { MutableDateTime sunday = (MutableDateTime) monday.clone(); sunday.addDays(-1); return sunday; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getMonday() { return monday; } /** * @param saturdayTime * pass a MutableDateTime to set this date of the CurrentWeek * object to the correct date for that week */ public void setMonday(MutableDateTime saturdayTime) { this.monday = saturdayTime; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getTuesday() { MutableDateTime tuesday = (MutableDateTime) monday.clone(); tuesday.addDays(1); return tuesday; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getWednesday() { MutableDateTime wednesday = (MutableDateTime) monday.clone(); wednesday.addDays(2); return wednesday; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getThursday() { MutableDateTime thursday = (MutableDateTime) monday.clone(); thursday.addDays(3); return thursday; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getFriday() { MutableDateTime friday = (MutableDateTime) monday.clone(); friday.addDays(4); return friday; } /** * @return a MutableDateTime which is of the correct date for this specific * day */ public MutableDateTime getSaturday() { MutableDateTime saturday = (MutableDateTime) monday.clone(); saturday.addDays(5); return saturday; } } 

最后是引用CurrentWeekController的jsp文件:

            Time Tracking Page      

User Time Tracking Page

Hours for the week of until
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
<input type="button" value="" onClick="clockInOrOutReloadPage()">

控制器应该是Spring MVC中的应用程序作用域(您不需要明确地将它们作为默认范围)。

任何请求级别数据都应使用模型属性完成:

 @ModelAttribute("foo") public Foo createFoo(@RequestParam("bar") int bar) { return new Foo(bar); } @RequestMapping(...) public ModelAndView baz(HttpServletRequest req, HttpServletResponse response, @ModelAttribute("foo") Foo foo) { ... } 

Spring将自动创建“Foo”实例(通过“createFoo”)方法并将其放入请求范围。 然后,通过在映射方法中注释方法参数,它将自动从请求范围中提取它并将其传递给您的方法。

如果要将模型属性存储在会话范围中,请将此批注添加到控制器类:

 @SessionAttributes({"foo"}) 

这意味着您不应该在控制器本身中具有任何状态,仅在模型属性中(无论是在请求范围还是在会话范围内),并且应该将该状态注入到映射方法调用中。

检查此链接https://jira.springsource.org/browse/SPR-5697如果在同一个请求映射的属性值中使用,则始终建议在控制器级别添加requestmapping属性,在方法级别添加requestmapping属性另一个控制器可能会显示此错误。 为了避免在控制器级别添加请求映射属性。

 @Controller @SessionAttributes("command"( @RequestMapping(value="CurrentWeek") @RequestMapping(value="TimeTracking.html" method="RequesstMethod.POST) public ModelAndView processForm(....){ } 

Controller的默认范围是Singleton。 除非你有充分的理由改变它,否则不要这样做。 Singleton适用于组件范围的会话