gpt4 book ai didi

java - 将 request 属性从 request 注入(inject)到 spring Controller 方法中

转载 作者:行者123 更新时间:2023-11-30 08:37:57 24 4
gpt4 key购买 nike

我有一些 spring @RestControllers 方法,我想将每个请求附带的值作为请求属性(包含用户)注入(inject),例如:

@RestController
@RequestMapping("/api/jobs")
public class JobsController {
// Option 1 get user from request attribute as prop somehow
private String userId = "user1";

// Option 2 inject into method using aspect or something else
@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Jobs>> getJobs() throws ResourceNotFoundException {
// currentUser is injected
this.getJobs(currentUser);
}

我知道我能做到:

@RestController
@RequestMapping("/api/jobs")
public class JobsController {

@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Jobs>> getJobs(HttpServletRequest request) throws ResourceNotFoundException {
String currentUser = null;
if (request.getAttribute("subject") != null) {
currentUser = request.getAttribute("subject").toString();
}
this.getJobs(currentUser);
}

但这需要我在程序中的每个方法中添加此代码,在我看来,这是一个非常糟糕的做法。
有办法实现我想要的吗?

如果答案确实需要方面,那么代码示例将非常感激,因为我只阅读了它,但从未真正对方面做过任何事情。

更新
我建议的代码可以使用以下内容进行简化:

@RestController
@RequestMapping("/api/jobs")
public class JobsController {

@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Jobs>> getJobs(@Value("#{request.getAttribute('subject')}" String currentUser) throws ResourceNotFoundException {
this.getJobs(currentUser);
}

但仍然要求我在每个方法中添加该参数。这个参数可以以某种方式注入(inject)到每个方法中吗?

最佳答案

您可以使用Filter填充 ThreadLocal<String>存储该属性的变量:

public class MyFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
ContextHolder.setSubject(request.getAttribute('subject'));
chain.doFilter(request, response);
}

@Override
public void destroy() {
ContextHolder.removeSubject();
}
}


public class ContextHolder {

private static final ThreadLocal<String> SUBJECT = new ThreadLocal<String>() {
@Override
protected String initialValue() {
return "empty";
}
};

public static void setSubject(String subject) {
SUBJECT.set(subject);
}

public static String getSubject() {
return SUBJECT.get();
}

public static void removeSubject() {
SUBJECT.remove();
}
}

过滤器将配置为拦截所有请求并填充 SUBJECT多变的。通过使用 ThreadLocal ,确保每个线程都有自己的 subject值(value)。现在,您可以通过调用 ContextHolder.getSubject() 在应用程序中的任何位置获取该值。 :

  @RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Jobs>> getJobs(HttpServletRequest request) throws ResourceNotFoundException {
this.getJobs(ContextHolder.getSubject());
}

您还必须注册 Filter在 web.xml 文件中:

<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

如果您有多个属性,您可以使用 ThreadLocal<Map<String, String>>而是变量。

关于java - 将 request 属性从 request 注入(inject)到 spring Controller 方法中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36838257/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com