当组件作为会话作用域时,无法将Spring控制器作为请求范围 [英] Cannot scope Spring controller as request when a component is scoped as session

查看:103
本文介绍了当组件作为会话作用域时,无法将Spring控制器作为请求范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试按照此网站上的指南正确定位我的bean以获取Spring网络应用:

I'm trying to follow the guide at this website to properly scope my beans for a Spring web app:

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

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

I'm trying to follow method 3, which basically means I want to scope my component classes as session, and therefore I have to scope my controller classes at request. I have the controller put into my JSP page so it can be used.

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

When I try to do this, though, my webapp has build issues, and when I try to go to the web page it gives me a 503 service_unavailable error.

构建错误是:


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

SEVERE: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0': Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler 'currentWeekController' to URL path [/TimeTracking]: There is already handler 'scopedTarget.currentWeekController' mapped.

以下是相关类和jsp页面。如果您还有其他需求,请直接询问!

Here are the relevant classes and the jsp page. If you need anything else please just ask!

CurrentWeekController控制器类:

CurrentWeekController Controller class:

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组件类。

And here is the CurrentWeek component class.

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;
    }

}

最后引用的jsp文件CurrentWeekController:

And finally the jsp file that references the CurrentWeekController:

<%@page contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page import="daos.*"%>
<%@page import="controllers.*"%>
<%@page import="models.*"%>

<jsp:useBean id="userDao" class="daos.UserDao" scope="request" />

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<jsp:useBean id="timeTrackingControl"
    class="controllers.TimeTrackingController" scope="request" />
<jsp:useBean id="currentWeek" class="controllers.CurrentWeekController"
    scope="request" />
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Time Tracking Page</title>
<script type="text/javascript" src= "../javascriptpages/timeTracking.js"></script>
<link rel="stylesheet" type="text/css" href="csspages/global.css" />

<style type="text/css"></style>
</head>

<body>

    <div>
        <h1>User Time Tracking Page</h1>

    </div>
    <div id="content">

    <form method="POST" action="../TimeTracking.html">
            <span> <input name="changeWeek" type="submit" value="Previous Week"/> Hours for the week of
                <%=currentWeek.firstDayOfThisWeek()%> until <%=currentWeek.lastDayOfThisWeek()%>
                <input name="changeWeek" type="submit" value="Next Week"/>
            </span>
    </form>


            <table border="1">
                <tr>
                    <th>Sunday</th>
                    <th>Monday</th>
                    <th>Tuesday</th>
                    <th>Wednesday</th>
                    <th>Thursday</th>
                    <th>Friday</th>
                    <th>Saturday</th>
                </tr>
                <tr>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getSunday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getMonday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getTuesday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getWednesday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getThursday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getFriday())%></td>
                    <td><%=timeTrackingControl.totalWorkTimeForOneDate(currentWeek.getCurrentWeek().getSaturday())%></td>
                </tr>
            </table>

            <input type="button" value="<%=timeTrackingControl.displayClockButton()%>"
                onClick="clockInOrOutReloadPage()">

    </div>

</body>
</html>


推荐答案

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

Controllers should be application scoped in Spring MVC (you don't need to explicitly scope them as that's the default).

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

Any request level data should be done using model attributes:

@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)方法并将其放在请求范围内。然后,通过在映射方法中注释方法参数,它会自动从请求范围中提取它并将其传递给您的方法。

Spring will automatically create the "Foo" instance (via your "createFoo") method and put it in request scope. Then, by annotating a method parameter in your mapped method, it will automatically pull that from request scope and pass it along to your method.

如果你想要一个模型属性存储在会话范围中,您将此注释添加到控制器类:

If you want a model attribute to be stored in session scope, you add this annotation to the controller class:

@SessionAttributes({"foo"})

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

This means you should not have any state in your controller itself, only in model attributes (whether at request or session scope), and should inject that state into your mapped method calls.

这篇关于当组件作为会话作用域时,无法将Spring控制器作为请求范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆