java 404页面找不到404页面找不到

ddrv8njm  于 2023-05-27  发布在  Java
关注(0)|答案(1)|浏览(125)

我正在升级一个遗留项目。目前正在从Spring 4升级到Spring 5。
登录工作正常,但由于密码过期,用户被带到更改密码屏幕。然而,我遇到了一个404错误,没有找到当试图达到它。
我想我已经正确地更新了它,以满足 Spring 5的要求,但它似乎仍然没有正确地Map。有人能在我的控制器中发现错误吗?
参考的jsp的路径是
/application/src/main/webapp/WEB-INF/jsp/public/change-password/change-password.jsp

app-security-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security.xsd 
          http://www.springframework.org/schema/util
          https://www.springframework.org/schema/util/spring-util.xsd" >
    
    <security:http
        auto-config="false"
        access-decision-manager-ref="accessDecisionManager"
        use-expressions="true"
        request-matcher="ant"
        disable-url-rewriting="true"
    >
        <security:headers>
            <security:hsts disabled="true"/>
            <security:frame-options policy="SAMEORIGIN"/>
        </security:headers>
        <security:csrf disabled="true"/>
        
        <!-- Set up URL security for specific pages -->
        <security:intercept-url pattern="/secure/home" access="hasRole('AUTH_LOGIN')" />
        <security:intercept-url pattern="/logout" access="hasRole('AUTH_LOGIN')" />
        <security:intercept-url pattern="/secure/help/**" access="hasRole('AUTH_LOGIN')" />
        <security:intercept-url pattern="/secure/help/contents" access="hasRole('AUTH_LOGIN')" />
        <security:intercept-url pattern="/secure/change-password" 
        
        <!-- Fall back for any other secure/* pages - user must be authenticated -->
        <security:intercept-url pattern="/secure/**" access="isAuthenticated()" />
        
        <!-- Allow anonymous access for any URLS not secured above -->
        <security:anonymous username="ANON" granted-authority="AUTH_ANON" />

        <!-- Set up concurrent session control, the logout page, and the access denied handler -->
        <security:session-management session-fixation-protection="newSession">
            <security:concurrency-control max-sessions="1" expired-url="/public/login?expired=true" />
        </security:session-management>
        
        <security:logout logout-url="/logout"
                         invalidate-session="true"
                         success-handler-ref="logOutSuccessHandler"
        />
        
        <security:access-denied-handler error-page="/public/forbidden" />
        
        <!-- Set up form login authentication, wiring up the success/and failure handlers -->
        <security:form-login 
            login-page="/public/login" 
            login-processing-url="/public/security_check"
            authentication-failure-handler-ref="authenticationFailureHandler"
            authentication-success-handler-ref="authenticationSuccessHandler"
        />
            
    </security:http>
 
    
    <bean id="authenticationSuccessHandler" class="com.app.application.util.spring.security.DefaultAuthenticationSuccessHandler">
        <constructor-arg ref="daoFactory" />
        <property name="defaultTargetUrl" value="/secure/home" />
        <property name="localeResolver" ref="localeResolver" />
    </bean>
    <bean id="authenticationFailureHandler" class="com.app.application.util.spring.security.DefaultAuthenticationFailureHandler">
        <constructor-arg ref="daoFactory" />
        <property name="defaultFailureUrl" value="/public/login?failed=true" />
        <property name="changePasswordUrl" value="/public/change-password" />
        <property name="suspendedUrl" value="/public/suspended" />
        <property name="deletedUrl" value="/public/deleted" />
    </bean>
    <bean id="logOutSuccessHandler" class="com.app.application.util.spring.security.DefaultLogOutSuccessHandler">
        <constructor-arg ref="daoFactory" />
        <property name="logOutUrl" value="/public/logout" />
    </bean>
    
    <bean class="com.app.application.security.DefaultRolesPrefixPostProcessor"/>
    
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter">
                    <property name="rolePrefix" value="AUTH_" />
                </bean>
                <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
                <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                    <property name="expressionHandler">
                        <bean id="expressionEvaluator" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
                    </property>
                </bean>
            </list>
        </constructor-arg>
    </bean>
    
    <!-- 
    Set up the authentication manager, giving it our security service and setting up the password hashing.  We must manually create the encoder and salt source
    beans as they are required by our security service. 
    -->
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="customAuthenticationProvider">
        </security:authentication-provider>
    </security:authentication-manager>
    
    <bean id="passwordEncoder" class="com.app.application.security.domain.password.Sha1DigestGenerator" />
    <bean id="saltSource" class="com.app.application.security.domain.password.UsernameSaltSource" />
    
    <!-- Configure password generator and password validator -->
    <bean id="passwordGenerator" class="com.app.application.security.domain.password.DefaultPasswordGenerator">
        <property name="randomStringGenerator">
            <bean class="com.amor.hcplus.application.util.ApacheCommonsLangRandomStringGenerator" />
        </property>
        <property name="digestGenerator" ref="passwordEncoder" />
        <property name="saltSource" ref="saltSource" />
        <property name="passwordValidator" ref="passwordValidator"/>
        <property name="generatedPasswordLength" value="8" />
    </bean>
    <bean id="passwordValidator" class="com.app.application.security.domain.password.DefaultPasswordValidator" />
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  
    <!--  Spring context -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:/com/amor/**/*-config.xml
            /WEB-INF/spring/**/*-config.xml
        </param-value>
    </context-param>
    
    <context-param>
        <param-name>htmlEscape</param-name>
        <param-value>true</param-value>
    </context-param>
    
    <!--  Application Exit Cleanup Listener --> 

    <listener>
        <listener-class>com.app.web.mvc.context.ApplicationExitCleanupListener</listener-class>
    </listener>

    <!-- OpenSessionInViewFilter -->
    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- Spring security -->
    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>     
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping> 
    
    <!-- Spring servlets -->
    <servlet>
        <servlet-name>public</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/public-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>public</servlet-name>
        <url-pattern>/public/*</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>secure</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/secure-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>secure</servlet-name>
        <url-pattern>/secure/*</url-pattern>
    </servlet-mapping>  
    
    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>dev</param-value>
    </context-param>
    <context-param>
        <param-name>spring.profiles.default</param-name>
        <param-value>dev</param-value>
    </context-param>
    <context-param>
        <param-name>spring.liveBeansView.mbeanDomain</param-name>
        <param-value>dev</param-value>
    </context-param>

    <!-- Other tomcat options -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
    <error-page>
        <error-code>403</error-code>
        <location>/public/forbidden</location>
    </error-page>
    
    <error-page>
        <error-code>500</error-code>
        <location>/public/error</location>
    </error-page>
    
</web-app>

public-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"
>

    <mvc:annotation-driven />
    <context:component-scan base-package="com.app">
        <context:include-filter type="annotation" expression="com.app.web.mvc.PublicController" />
    </context:component-scan>
    <mvc:annotation-driven />
    <!--<context:annotation-config></context:annotation-config>-->
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/public/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
</beans>

PublicChangePasswordController.java

@PublicController
@RequestMapping("/change-password")
@SessionAttributes("changePasswordFormObject")
public class PublicChangePasswordController {

    private SecurityService securityService;

    @Autowired
    public PublicChangePasswordController(SecurityService securityService) {
        super();
        this.securityService = securityService;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setValidator(new ChangePasswordFormObjectValidator(securityService));
    }

    @RequestMapping(value = "/change-password", method = RequestMethod.GET)
    public ModelAndView display(WebRequest webRequest) {

        String username = (String) webRequest.getAttribute(DefaultAuthenticationFailureHandler.PASSWORD_CHANGE_USERNAME, RequestAttributes.SCOPE_SESSION);

        if (!StringUtils.hasText(username)) {
            // Redirect if no username is found on the session - user must have accessed it directly
            return new ModelAndView("redirect:/");
        }

        ChangePasswordFormObject formObject = new ChangePasswordFormObject();
        formObject.setUsername(username);

        ModelAndView modelAndView = new ModelAndView("change-password/change-password");
        modelAndView.addObject("changePasswordFormObject", formObject);

        return modelAndView;
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String changePassword(@ModelAttribute("changePasswordFormObject") @Valid ChangePasswordFormObject formObject, BindingResult bindingResult,
            WebRequest webRequest, SessionStatus sessionStatus) throws Exception {

        if (bindingResult.hasErrors()) {
            return "change-password/change-password";
        }

        ChangePasswordDetailsDto changePasswordDetailsDto = new ChangePasswordDetailsDto();
        changePasswordDetailsDto.setUsername(formObject.getUsername());
        changePasswordDetailsDto.setNewPassword(formObject.getNewPassword());

        securityService.changePassword(changePasswordDetailsDto);

        webRequest.removeAttribute(DefaultAuthenticationFailureHandler.PASSWORD_CHANGE_USERNAME, RequestAttributes.SCOPE_SESSION);
        sessionStatus.setComplete();

        return "redirect:/";
    }
}

缺省公共控制器

@PublicController
@RequestMapping("/*")
public class DefaultPublicController {

    private String servletContext = "public/";

    @RequestMapping
    public String handle(HttpServletRequest request) {
        return request.getRequestURI().substring(request.getRequestURI().lastIndexOf(servletContext) + servletContext.length());
    }
}
xxslljrj

xxslljrj1#

我看到你的classPublicChangePasswordController用@RequestMapping("/change-password")注解。
方法display()有@RequestMapping(value = "/change-password", method = RequestMethod.GET)。你的链接已经是:/change-password/change-password 不正确。删除display()方法中的注解,只使用@GetMapping

@GetMapping("/change-password")
public ModelAndView display(WebRequest webRequest) {
    // Method implementation
}

你也可以用@PostMappting更新changePassword(),但不要忘记添加路径:/保存

根据评论:在xml中检查此代码。有两<mvc:annotation-driven />种,但也许应该是mvc:注解驱动和<mvc:annotation-driven />

<mvc:annotation-driven />
<context:component-scan base-package="com.app">
    <context:include-filter type="annotation" expression="com.app.web.mvc.PublicController" />
</context:component-scan>
<mvc:annotation-driven />

玩这条线。因为您正在更新ModelAndView

ModelAndView modelAndView = new ModelAndView("public/change-password/change-password");

相关问题