Edit я добавил более подробно, чтобы помочь другим и оставил оригинальный вопрос для историиPopulate объект на вызов метода Spring Controller
фона Я прототип REST вызова, который возвращает JSON в Spring Controller, который работает с мое клиентское программное обеспечение. Клиентское программное обеспечение имеет конкретный способ запроса данных. Этот запрос несовместим с моим кодом Spring, поэтому у меня было несколько строк, которые сделали преобразование. Я преобразовал код преобразования в свой собственный объект. Вместо того чтобы создавать каждый раз в моих методах REST, которые его требуют, я хотел бы, чтобы он был предварительно заполнен до того, как он дойдет до моего метода.
Вопрос В контроллере весны я могу установить Spring, предварительно заполнив объект из значений в URL-адресе и заголовке, подобно тому, как Spring заполняет и объект из формы?
Текущий код
@RequestMapping(value="", headers = "Accept=application/json", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<String> searchUserProjects(
@RequestParam(required = false) String projectName,
@RequestParam(required = false) String sortBy,
@RequestHeader(value = "Range") String range) {
Оригинал Вопрос Я знаю, что весной вы можете принять свойства формы и отобразить их на объект. Кроме того, я знаю, что вы можете сопоставить поле с объектом преобразования свойств, я не могу вспомнить точное имя, но я это сделал. Мой вопрос: возможно ли, чтобы Spring заполнила объект из значений в URL-адресе и заголовке, а затем передала это в метод вместо того, чтобы объявить их на сигнатуре метода контроллера?
Edit:
Метод регистрации в applicationContext.xml
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="app.util.dojo.DojoQueryProcessorHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
И метод обработчика с параметром
public ResponseEntity<String> searchUserProjects(@RequestParam(required = false) String projectName, @ProcessDojoQuery DojoRestQueryProcessor dojoQueryResults) {
DojoRestQueryProcessor.java
package app.util.dojo;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
public class DojoRestQueryProcessor {
protected String[] rangeArray;
protected String range;
protected String sortBy;
protected int startIndex;
protected int endIndex;
public DojoRestQueryProcessor() {
}
public DojoRestQueryProcessor(String range, String sortBy) {
if (range== null && sortBy == null)
return;
if (range.length() <= 3 || !range.contains("-"))
throw new DojoRestQueryProcessorException("Range value does not meet spec. " + range);
this.rangeArray = range.substring(6).split("-");
this.range = range;
this.sortBy = sortBy;
}
public PageRequest createPageRequest() {
startIndex = Integer.parseInt(rangeArray[0]);
endIndex = Integer.parseInt(rangeArray[1]);
if (startIndex >= endIndex)
throw new IllegalArgumentException("The starting index for a range needs to be less than the end index.");
Sort.Order[] sortOrders = null;
if (sortBy != null && sortBy.length() > 2)
sortOrders = convertDojoSortValuesToSpringSorts(sortBy.split(","));
int pageSize = endIndex-startIndex+1;
int pageNum = ((endIndex+1)/pageSize)-1;
PageRequest pageRequest = null;
if (sortOrders != null)
pageRequest = new PageRequest(pageNum, pageSize, new Sort(sortOrders));
else
pageRequest = new PageRequest(pageNum, pageSize);
return pageRequest;
}
public static Sort.Order[] convertDojoSortValuesToSpringSorts(String[] sortStrings) {
if (sortStrings == null)
return null;
Sort.Order[] sortOrders = new Sort.Order[sortStrings.length];
for (int i = 0; i < sortStrings.length; i++) {
String sortString = sortStrings[i];
if (sortString.startsWith("-")) {
sortOrders[i] = new Sort.Order(Direction.DESC, sortString.substring(1));
} else {
sortOrders[i] = new Sort.Order(Direction.ASC, sortString.substring(1));
}
}
return sortOrders;
}
public int getStartIndex() {
return startIndex;
}
public int getEndIndex() {
return endIndex;
}
public String getRange() {
return range;
}
public String getSortBy() {
return sortBy;
}
}
Мой метод Handler:
package app.util.dojo;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.HandlerMapping;
public class DojoQueryProcessorHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(ProcessDojoQuery.class) && parameter.getParameterType().equals(DojoRestQueryProcessor.class) ;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
throws Exception {
String rangeField = parameter.getParameterAnnotation(ProcessDojoQuery.class).rangeField();
String sortByField = parameter.getParameterAnnotation(ProcessDojoQuery.class).sortByField();
String range = getRangeValue(rangeField, webRequest);
String sortBy = getSortByValue(sortByField, webRequest);
return new DojoRestQueryProcessor(range, sortBy);
}
private String getSortByValue(String rangeField, NativeWebRequest webRequest) {
Map<String, String> pathVariables = getPathVariables(webRequest);
return pathVariables.get(rangeField);
}
private Map<String, String> getPathVariables(NativeWebRequest webRequest) {
HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
return (Map<String, String>) httpServletRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
}
private String getHeaderValue(String headerName, NativeWebRequest webRequest) {
HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
return httpServletRequest.getHeader(headerName);
}
private String getRangeValue(String rangeField, NativeWebRequest webRequest) {
return getHeaderValue(rangeField, webRequest);
}
}
Спасибо за ваш ответ. Мне это очень полезно. – SerotoninChase
Похоже, что это сработает. Я еду прямо сейчас, поэтому завтра буду проверять. – Joe
Я создал код и зарегистрировал его. Во время запуска появляется аргумент resolver. Однако объект создается Spring и не вызывает мой код. Любые мысли о том, как исправить это? – Joe