Java Spring Boot - 如何获取请求的基本 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21239517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:33:28  来源:igfitidea点击:

Spring Boot - how do I get the base url of a request

javaspringspring-mvcspring-boot

提问by Lurk21

I'm running a spring boot and a few of my domain services need to know the domain name.

我正在运行 Spring Boot,我的一些域服务需要知道域名。

I know that I could capture it at the application layer in the controller method like this:

我知道我可以在控制器方法的应用程序层捕获它,如下所示:

 @RequestMapping(value="/myMapping",method = RequestMethod.POST)
 public ModelandView myAction(HttpServletRequest request) {

 }

OR that, if I were running a traditional web application with a war that I could configure a listener like this:

或者,如果我正在运行一个带有战争的传统 Web 应用程序,我可以像这样配置一个侦听器:

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

And access it like this:

并像这样访问它:

((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()

But I do not want to pass around arguments like I would if I captured it at the controller, and I am not running a war with a web.xml.

但是我不想像在控制器中捕获它那样传递参数,并且我没有与 web.xml 进行一场战争。

How can I have my cake and eat it too?

我怎样才能拥有我的蛋糕并吃掉它?

采纳答案by Lurk21

This is what I did:

这就是我所做的:

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class RequestFetcher {
    public static HttpServletRequest getCurrentRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        Assert.state(requestAttributes != null, "Could not find current request via RequestContextHolder");
        Assert.isInstanceOf(ServletRequestAttributes.class, requestAttributes);
        HttpServletRequest servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
        Assert.state(servletRequest != null, "Could not find current HttpServletRequest");
        return servletRequest;
    }
}

回答by SergeyB

If you use Spring Security, you could store this info in SecurityContext. The trick is getDetails() method, you can put anything you want in there. I personally use a custom object that stores basic info I need for the current user. This example just puts a simple string representing your domain:

如果您使用 Spring Security,则可以将此信息存储在 SecurityContext 中。诀窍是 getDetails() 方法,你可以把你想要的任何东西放进去。我个人使用一个自定义对象来存储当前用户所需的基本信息。这个例子只是把一个简单的字符串代表你的域:

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

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

@Component
public class DomainInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String domain = null; // TODO extra domain from request here
        SecurityContext context = SecurityContextHolder.getContext();
        AbstractAuthenticationToken authentication = (AbstractAuthenticationToken) context.getAuthentication();
        authentication.setDetails(domain);
        return true;
    }
}

Then to retrieve the domain (for the current request) anywhere in your app you'd do this:

然后要在您的应用程序中的任何位置检索域(针对当前请求),您可以执行以下操作:

String domain = SecurityContextHolder.getContext().getAuthentication().getDetails().toString();

回答by Chloe

I don't know what you mean by "I'm not running a WAR" but the question is tagged Spring-MVC which is for web applications. Anyways this is how you can get the domain of the request. When a browser makes a request it sends the host name as part of the HTTP request header for multi-domain web hosting. For HTTPS, Server Name Identificationis the same thing.

我不知道你所说的“我没有运行 WAR”是什么意思,但这个问题被标记为 Spring-MVC,它是针对 Web 应用程序的。无论如何,这就是您获取请求域的方法。当浏览器发出请求时,它会发送主机名作为多域 Web 托管的 HTTP 请求标头的一部分。对于 HTTPS,服务器名称标识是一回事。

@RequestMapping(value = "/server/path")
public void request(
        @RequestHeader(name="Host", required=false) final String host,