Аннотированный контроллер Spring-MVC не распознается, когда контроллер расширяет интерфейс - PullRequest
5 голосов
/ 30 сентября 2008

Я использую Spring 2.5 и использую аннотации для настройки моих контроллеров. Мой контроллер работает нормально, если я не реализую никаких дополнительных интерфейсов, но контейнер Spring не распознает отображение контроллера / запроса при добавлении реализаций интерфейса.

Я не могу понять, почему добавление реализации интерфейса портит конфигурацию контроллера и отображения запросов. Есть идеи?

Итак, это работает:

package com.shaneleopard.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.shaneleopard.model.User;
import com.shaneleopard.service.UserService;
import com.shaneleopard.validator.RegistrationValidator;
import com.shaneleopard.web.command.RegisterCommand;

@Controller
public class RegistrationController {

    @Autowired
    private UserService userService;

    @Autowired
    private Md5PasswordEncoder passwordEncoder;

    @Autowired
    private RegistrationValidator registrationValidator;

    @RequestMapping( method = RequestMethod.GET, value = "/register.html" )
    public void registerForm(@ModelAttribute RegisterCommand registerCommand) {
        // no op
    }

    @RequestMapping( method = RequestMethod.POST, value = "/register.html" )
    public String registerNewUser( @ModelAttribute RegisterCommand command,
            Errors errors ) {
        String returnView = "redirect:index.html";

        if ( errors.hasErrors() ) {
            returnView = "register";
        } else {
            User newUser = new User();
            newUser.setUsername( command.getUsername() );
            newUser.setPassword( passwordEncoder.encodePassword( command
                    .getPassword(), null ) );
            newUser.setEmailAddress( command.getEmailAddress() );
            newUser.setFirstName( command.getFirstName() );
            newUser.setLastName( command.getLastName() );

            userService.registerNewUser( newUser );
        }
        return returnView;

    }

    public Validator getValidator() {
        return registrationValidator;
    }
}

но это не так:

package com.shaneleopard.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.shaneleopard.model.User;
import com.shaneleopard.service.UserService;
import com.shaneleopard.validator.RegistrationValidator;
import com.shaneleopard.web.command.RegisterCommand;

@Controller
public class RegistrationController extends ValidatingController {

    @Autowired
    private UserService userService;

    @Autowired
    private Md5PasswordEncoder passwordEncoder;

    @Autowired
    private RegistrationValidator registrationValidator;

    @RequestMapping( method = RequestMethod.GET, value = "/register.html" )
    public void registerForm(@ModelAttribute RegisterCommand registerCommand) {
        // no op
    }

    @RequestMapping( method = RequestMethod.POST, value = "/register.html" )
    public String registerNewUser( @ModelAttribute RegisterCommand command,
            Errors errors ) {
        String returnView = "redirect:index.html";

        if ( errors.hasErrors() ) {
            returnView = "register";
        } else {
            User newUser = new User();
            newUser.setUsername( command.getUsername() );
            newUser.setPassword( passwordEncoder.encodePassword( command
                    .getPassword(), null ) );
            newUser.setEmailAddress( command.getEmailAddress() );
            newUser.setFirstName( command.getFirstName() );
            newUser.setLastName( command.getLastName() );

            userService.registerNewUser( newUser );
        }
        return returnView;

    }

    public Validator getValidator() {
        return registrationValidator;
    }
}

Ответы [ 3 ]

3 голосов
/ 13 октября 2008

layne , вы описали проблему как возникающую, когда ваш класс контроллера реализует интерфейс, но в предоставленном вами примере кода проблема возникает, когда ваш класс контроллера расширяет другой ваш класс, ValidatingController.

Возможно, родительский класс также определяет некоторые аннотации Spring, и контейнер Spring сначала заметил их и классифицировал класс контроллера как тип управляемого объекта и не удосужился проверить аннотацию @Controller, которую вы также определили в подклассе. Просто предположение, но если это удастся, я бы предложил сообщить об этом команде Spring, поскольку это звучит как ошибка.

0 голосов
/ 06 июня 2013

По умолчанию JDK-прокси создается с использованием интерфейса, и если контроллер реализует интерфейс, аннотация RequestMapping игнорируется, так как targetClass не используется

Добавьте это в конфигурацию вашего сервлета:

<aop:aspectj-autoproxy proxy-target-class="true"/>
0 голосов
/ 09 октября 2008

Я думаю, вы обнаружите, что проблема связана с наследованием и использованием аннотаций, они плохо сочетаются.

Вы пытались реализовать вышеизложенное с использованием наследования и SimpleFormController со всеми другими деталями, настроенными в контексте вашего приложения? Это как минимум сузит проблему до аннотации и наследования.

...