У меня есть несколько весенних методов @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);
}
Но все же требуйте, чтобы я добавлял этот параметр в каждый метод. Можно ли каким-то образом ввести этот параметр в каждый метод?
3 ответа
Вы можете использовать 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());
}
Вам также необходимо зарегистрировать 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>>
.
Просто добавьте @ResuestAttribute
в свой остальной
@RestController
@RequestMapping(path="/yourpath")
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity getAll(
@RequestAttribute(value = "yourAttribute") Object
YourAttribute ......
Если вы действительно хотите узнать об атрибутах, вам следует проверить spring @ 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);
}
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.