如何使用Spring MVC和Spring Security

时间:2016-05-24 13:42:18

标签: spring hibernate jsp spring-mvc spring-security

我有profile.jsp。其目前有关授权用户的信息。

<div class='contacts'>Contacts</div>
   <table>
       <tr><th>E-mail</th><td><div>${email}</div></td></tr>
       <tr><th>Phone number</th><td><div>${phone}</div></td></tr>
       <tr><th>Name</th><td><div>${name}</div></td></tr>
       <tr><th>Surname</th><td><div>${surname}</div></td></tr>
       <tr><th>Middle name</th><td><div>${middleName}</div></td></tr>
   </table>

这是个人资料控制器

@RequestMapping(value = "/user/profile")
    public ModelAndView userProfile(Principal principal){
        ModelAndView modelAndView = new ModelAndView();
        UserEntity userEntity = userService.getByEmail(principal.getName());
        modelAndView.addObject("userName", userEntity.getName());
        modelAndView.addObject("email", userEntity.getEmail());
        modelAndView.addObject("phone",userEntity.getPhone());
        modelAndView.addObject("name", userEntity.getName());
        modelAndView.addObject("surname", userEntity.getSurname());
        modelAndView.addObject("middleName", userEntity.getMiddleName());
        modelAndView.setViewName("profile");
        return modelAndView;
    }

这是update_user.jsp

<c:url value="/user/profile/update" var="updateProfile"/>
<form enctype="multipart/form-data" class="form-horizontal" id="loginModalForm" action="${updateProfile}" method="post">
    <input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}" />
    <div class="form-group"><label class="col-sm-3 control-label" for="User_name">Name</label>
        <div class="col-sm-9"><input class="form-control" placeholder="Name" name="userName" id="User_name" type="text" maxlength="50" value="${userName}" />
            <div class="help-block error" id="User_name_em_" style="display:none"></div>
        </div>
    </div>

    <div class="form-group"><label class="col-sm-3 control-label" for="User_surname">Surname</label>
        <div class="col-sm-9"><input class="form-control" placeholder="Surname" name="userSurname" id="User_surname" type="text" maxlength="50" value="${userSurname}" />
            <div class="help-block error" id="User_surname_em_" style="display:none"></div>
        </div>
    </div>

    <div class="form-group"><label class="col-sm-3 control-label" for="User_middle_name">Middle name</label>
        <div class="col-sm-9"><input class="form-control" placeholder="Middle name" name="userMiddleName" id="User_middle_name" type="text" maxlength="50" value="${userMiddleName}" />
            <div class="help-block error" id="User_middle_name_em_" style="display:none"></div>
        </div>
    </div>

    <div class="form-group"><label class="col-sm-3 control-label required" for="User_phone">Phone number <span class="required">*</span></label>
        <div class="col-sm-9"><input class="form-control" placeholder="Phone number" name="userPhone" id="User_phone" type="text" maxlength="14" value="${userPhone}" />
            <div class="help-block error" id="User_phone_em_" style="display:none"></div>
        </div>
    </div>

    <button class="btn btn-primary" id="yw1" type="submit" name="yt0">Update</button>
</form>

及其控制器

 @RequestMapping(value = "/user/profile/update") 
public ModelAndView userProfileUpdate(HttpServletRequest request, Principal principal){
    ModelAndView modelAndView = new ModelAndView();
    UserEntity userEntity = userService.getByEmail(principal.getName());
    modelAndView.setViewName("update_user");
    modelAndView.addObject("userName", userEntity.getName());
    modelAndView.addObject("userSurname", userEntity.getSurname());
    modelAndView.addObject("userMiddleName", userEntity.getMiddleName());
    modelAndView.addObject("userPhone", userEntity.getPhone());
    String userName = request.getParameter("userName");
    String userSurname = request.getParameter("userSurname");
    String userMiddleName = request.getParameter("userMiddleName");
    String userPhone = request.getParameter("userPhone");
    userEntity.setName(userName);
    userEntity.setSurname(userSurname);
    userEntity.setMiddleName(userMiddleName);
    userEntity.setPhone(userPhone);
    userService.update(userEntity);
    return new ModelAndView(new RedirectView("/user/profile"));

我的userProfileUpdate有什么问题?当我尝试转到update_user.jsp时出现错误:

type Exception report

message Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
root cause

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    com.sun.proxy.$Proxy75.save(Unknown Source)
    edinar.service.impl.UserServiceImpl.update(UserServiceImpl.java:43)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:483)
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    com.sun.proxy.$Proxy77.update(Unknown Source)
    edinar.controllers.UserController.userProfileUpdate(UserController.java:208)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:483)


root cause

javax.persistence.RollbackException: Error while committing the transaction
    org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:86)
    org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    com.sun.proxy.$Proxy75.save(Unknown Source)
    edinar.service.impl.UserServiceImpl.update(UserServiceImpl.java:43)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

root cause

javax.validation.ConstraintViolationException: Validation failed for classes [edinar.entity.UserEntity] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=phone, rootBeanClass=class edinar.entity.UserEntity, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=password, rootBeanClass=class edinar.entity.UserEntity, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
]
    org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
    org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:86)
    org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:244)
    org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:118)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
    org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
    org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)
    org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
    org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
    org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
    org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
    org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    com.sun.proxy.$Proxy75.save(Unknown Source)
    edinar.service.impl.UserServiceImpl.update(UserServiceImpl.java:43)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:483)
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    com.sun.proxy.$Proxy77.update(Unknown Source)

My SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserService userService;

    @Autowired
    UloginService uloginService;


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new UloginAuthentifiactionProvider());
    }

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;


    @Autowired
    public void registerGlobalAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        UloginAuthenticationFilter uloginFilter =
                new UloginAuthenticationFilter("/ulogin","http://localhost:8080/", uloginService, userDetailsService, userService);
        uloginFilter.setAuthenticationManager(authenticationManager());
        HttpSecurity httpSecurity = http.
                addFilterBefore(uloginFilter, AnonymousAuthenticationFilter.class);
        httpSecurity.authorizeRequests().antMatchers("/").permitAll()
                .anyRequest().authenticated() ;
        httpSecurity.formLogin().loginPage("/"); 

        http
                .addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                .antMatchers("/resources/**", "/**").permitAll()
                .anyRequest().permitAll()
                .and()
                .exceptionHandling().accessDeniedPage("/403");

        http.formLogin()
                .loginProcessingUrl("/user/login")
                .usernameParameter("loginemail")
                .passwordParameter("loginpassword")
                .successHandler(loginSuccessHandler())
                .failureHandler(loginFailureHandler())
                .permitAll();

        http.logout()
                .permitAll()
                .logoutUrl("/user/logout")
                .logoutSuccessUrl("/")
                .invalidateHttpSession(true)
                .and()
                .csrf().ignoringAntMatchers("/ulogin","/user/verify");

    }

}

1 个答案:

答案 0 :(得分:0)

userProfileUpdate()方法既设置update_user.jsp,又在显示update_user.jsp页面之前更新用户实体对象。尝试将逻辑拆分为两个方法,一个用于设置update_user.jsp,另一个用于处理调用userservice.update()方法的帖子,如下所示。

@RequestMapping(value = "/user/profile/update", method=RequestMethod.GET) 
public ModelAndView userProfileUpdate(HttpServletRequest request, Principal principal){
    ModelAndView modelAndView = new ModelAndView();
    UserEntity userEntity = userService.getByEmail(principal.getName());
    modelAndView.setViewName("update_user");
    modelAndView.addObject("userName", userEntity.getName());
    modelAndView.addObject("userSurname", userEntity.getSurname());
    modelAndView.addObject("userMiddleName", userEntity.getMiddleName());
    modelAndView.addObject("userPhone", userEntity.getPhone());
    return modelAndView;
}

@RequestMapping(value = "/user/profile/updatePost", method=RequestMethod.POST) 
public ModelAndView userProfileUpdatePost(HttpServletRequest request, Principal principal){
    ModelAndView modelAndView = new ModelAndView();
    UserEntity userEntity = userService.getByEmail(principal.getName());
    String userName = request.getParameter("userName");
    String userSurname = request.getParameter("userSurname");
    String userMiddleName = request.getParameter("userMiddleName");
    String userPhone = request.getParameter("userPhone");
    userEntity.setName(userName);
    userEntity.setSurname(userSurname);
    userEntity.setMiddleName(userMiddleName);
    userEntity.setPhone(userPhone);
    userService.update(userEntity);
    return new ModelAndView(new RedirectView("/user/profile"));
}