2016-04-25 27 views
1

我有一些彈簧@RestControllers方法,我想使用隨作爲請求屬性(包含用戶)每個請求的值來注入類似:進樣請求屬性彈控制器方法

@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); 
} 

但仍需要我在每一個方法添加參數。 該參數可以以某種方式注入每種方法嗎?

+0

你讀過[參考指南](http://docs.spring.io/彈簧/文檔/電流/彈簧的框架參考/ HTML/mvc.html#MVC-ANN-requestheader)?你不需要一個方面,因爲它支持開箱即用......不要讓事情變得更復雜,然後需要。 –

+0

我似乎無法理解它是如何開箱即用的?我需要把這段代碼放在每一種方法上,我想避免它。 – Osher

+0

如果是JWT,那麼我強烈建議不要設置屬性與請求正確集成並使用委託人。這樣你可以在請求上執行'getPrincipal'或者簡單地將'Principal'添加到方法簽名中。如果你使用Spring Security解碼JWT,你可以免費獲得這種支持(以及你需要的配置)。 –

回答

0

你可以使用一個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值。現在,您可以通過調用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()); 
    } 

您還必須註冊在web.xml文件中Filter

<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>>變量。

0

如果你真的想知道屬性,那麼你應該看看春天的@RequestParam註釋。你會使用這樣的:

@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<List<Jobs>> getJobs(@RequestParam("subject") String currentUser) throws ResourceNotFoundException { 
    this.getJobs(currentUser); 
} 
+0

由於數據位於請求屬性處,@Header屬性對我無效。而我得到這樣的用戶的原因是我使用jwt,並且在我的控制器之前有一個過濾器,從令牌中接收用戶並將其放在請求上。 – Osher

+0

好的,我已經更新了答案。它確實很簡單。 –

+0

我需要的是@Value(「#{request.getAttribute(‘主體’)}」,但仍需要爲每一個方法的重複。Iv'e更新的問題,感謝您的幫助 – Osher

0

只是簡單地添加@ResuestAttribute在你休息contorller

@RestController 
@RequestMapping(path="/yourpath") 

@RequestMapping(method = RequestMethod.GET) 
    public ResponseEntity getAll(
      @RequestAttribute(value = "yourAttribute") Object 

yourAttribute ......