首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >request.getRequestURI总是返回"/error“

request.getRequestURI总是返回"/error“
EN

Stack Overflow用户
提问于 2017-05-14 12:35:53
回答 5查看 2.4K关注 0票数 2

在一个webapp中,我使用Spring & MVC构建,并试图拒绝所有URL的访问,但对于未登录的用户,/signin除外。为了实现这一点,我设置了一个HandlerInterceptor实现,preHandler应该将所有非有效请求路由到/signin页面。

设置:

LoginViewController

代码语言:javascript
复制
package com.controller;

import com.model.UserDao;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping(value = "/signin")
@SessionAttributes("username")
public class LoginViewController {
    @Autowired
    private UserService userService;

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView showLoginForm(){
        return new ModelAndView("login");
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView verifyLogin(HttpServletRequest request, HttpSession session) {
        ModelAndView modelAndView;
        String username = request.getParameter("username");
        // if login fails, set reload login page
        if (userService.verifyUserLogin(username,request.getParameter("password")) == null){
            modelAndView = new ModelAndView("login");
            modelAndView.addObject("login_failed", true);
        } else {
            modelAndView = new ModelAndView("index");
            session.setAttribute("username", username);
        }
        return modelAndView;
    }
}

AccessInterceptor

代码语言:javascript
复制
package com.spring.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;

public class AccessInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception {
        System.out.println(request.getRequestURI());

        try {
            if (!request.getRequestURI().endsWith("/signin")) {
                if (request.getSession()
                        .getAttribute("username") == null) {
                    response.sendRedirect(request.getContextPath() + "/signin");
                    return false;
                }

            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("Post-handle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("After completion handle");
    }
}

WebApplicationConfig

代码语言:javascript
复制
package com.spring;

import com.spring.interceptor.AccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
@EnableWebMvc
public class WebApplicationConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(
                new AccessInterceptor()).
                addPathPatterns("/**").
                excludePathPatterns("/signin/**").
                excludePathPatterns("/static/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

}

WebApplicationInitializer

代码语言:javascript
复制
package com.spring;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext =
                new AnnotationConfigWebApplicationContext();
        rootContext.register(WebApplicationConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext =
                new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(MyWebAppInitializer.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/*");
        dispatcher.addMapping("*.css");
        dispatcher.addMapping("*.eot");
        dispatcher.addMapping("*.svg");
        dispatcher.addMapping("*.ttf");
        dispatcher.addMapping("*.woff");
        dispatcher.addMapping("*.map");
        dispatcher.addMapping("*.js");
        dispatcher.addMapping("*.ico");
    }

}

现在的问题是,System.out.println(request.getRequestURI())在AccessInterceptor中总是打印/error。因此,即使在调用/signin时,请求也总是被重定向。另一件有趣的事情是,即使配置了dispacher映射,也不会呈现CSS或其他静态资源。

有什么想法吗?

EN

回答 5

Stack Overflow用户

发布于 2019-05-29 09:02:26

如果您丢失了有效负载,api url将无法识别。至少放点东西

票数 0
EN

Stack Overflow用户

发布于 2019-07-22 16:08:31

我也遇到了这个问题,在WebLogIntercept(您的MyWebAppInitializer)类中,我使用以下代码解决了这个问题

加上这两个功能

代码语言:javascript
复制
    private Class getClassByName(Class classObject, String name){
        Map<Class,List<Field>> fieldMap = new HashMap<>();
        Class returnClass = null;
        Class tempClass = classObject;
        while (tempClass != null) {
            fieldMap.put(tempClass,Arrays.asList(tempClass .getDeclaredFields()));
            tempClass = tempClass.getSuperclass();
        }

        for(Map.Entry<Class,List<Field>> entry: fieldMap.entrySet()){
            for (Field f : entry.getValue()) {
                if(f.getName().equals(name)){
                    returnClass = entry.getKey();
                    break;
                }
            }
        }
        return returnClass;
    }

    private Object findCoyoteRequest(Object request)  throws Exception {
        Class a = getClassByName(request.getClass(),"request");
        Field request1 = a.getDeclaredField("request");
        request1.setAccessible(true);
        Object b = request1.get(request);
        if(getClassByName(b.getClass(),"coyoteRequest") == null){
            return findCoyoteRequest(b);
        }else{
            return b;
        }

并使用以下代码

代码语言:javascript
复制
Object a = findCoyoteRequest(request);
Field coyoteRequest = a.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object b = coyoteRequest.get(a);

Field uriMB = b.getClass().getDeclaredField("uriMB");
uriMB.setAccessible(true);
MessageBytes c = (MessageBytes)uriMB.get(b);
System.out.println(c.getString());

c.getString()是realuri

我的英语不好,希望有用

票数 0
EN

Stack Overflow用户

发布于 2019-11-12 11:28:00

禁用CFR对我有效参见https://www.baeldung.com/spring-security-csrf

代码语言:javascript
复制
@Override
protected void configure(HttpSecurity http) throws Exception {
   http.csrf().disable();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43963960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档