Мой последний блог, посвященный поддержке Spring для Matrix Variables, был сосредоточен на объяснении того, что они из себя представляют и почему вы хотите их использовать. Разобравшись, что и почему , этот блог посвящен тому, как и как вы их используете. Я также привел несколько примеров Matrix URI, и поэтому неплохо продемонстрировать некоторый код, который обрабатывает пару из них.
Примеры были
http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.40,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07 http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.90,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07/account;name=roger;number=105;location=stoke-on-trent,uk
Как и следовало ожидать, при написании кода для обработки матричных переменных ребята из Spring опираются на существующую инфраструктуру Spring MVC, вводя новую аннотацию @MatrixVariable. Это используется для аннотирования аргументов метода обработчика запросов, чтобы Spring мог вставлять соответствующие биты матрицы uri. @MatrixVariable имеет четыре аргумента: value, defaultValue, pathVar и required, и все они полностью объяснены в javadocs Springs .
И так к некоторому коду … Если вы помните в моем последнем блоге на эту тему, я выбрал сценарий, который имеет дело с обработкой множества цен на акции / акции, и пример приложения, доступного на Github , использует Matrix URI, разбирает его и добавляет в модель для отображения JSP.
При написании кода, первое, что нужно сделать, это создать новый контроллер для обработки URI …
@Controller @RequestMapping(value = "/matrixvars") public class MatrixVariableController { private static final Logger logger = LoggerFactory.getLogger(MatrixVariableController.class); }
В коде я добавил аннотацию @RequestMapping уровня класса, которая содержит первый блок моих URI: matrixvars. Это полезная вещь, так как она направляет все URI, которые содержат значение matrixvar, как первый элемент пути к этому контроллеру и экономит много дублирования.
Следующее, что нужно сделать, это добавить некоторый код в этот класс, который имеет дело с первым URI:
http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.40,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07
Первый метод обработчика запроса:
@RequestMapping(value = "/{stocks}", method = RequestMethod.GET) public String showPortfolioValues(@MatrixVariable Map<String, List<String>> matrixVars, Model model) { logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars }); List<List<String>> outlist = map2List(matrixVars); model.addAttribute("stocks", outlist); return "stocks"; } private List<List<String>> map2List(Map<String, List<String>> stocksMap) { List<List<String>> outlist = new ArrayList<List<String>>(); Collection<Entry<String, List<String>>> stocksSet = stocksMap.entrySet(); for (Entry<String, List<String>> entry : stocksSet) { List<String> rowList = new ArrayList<String>(); String name = entry.getKey(); rowList.add(name); List<String> stock = entry.getValue(); rowList.addAll(stock); outlist.add(rowList); } return outlist; }
взглянув на аннотацию @RequestMapping, вы увидите, что я присвоил ей значение / {stocks}. В сочетании с аннотацией уровня @RequestMapping это будет указывать Spring на сопоставление любых соответствующих запросов этому методу. Текст внутри фигурных скобок {stocks} указывает, что эту часть URI можно проанализировать и вставить в соответствующий аргумент метода.
Далее взгляните на аннотацию @MatrixVariable. Это аккуратно перед аргументом, в который я хочу ввести данные о запасах; однако, немного хитрая вещь здесь — получить правильный тип аргумента. Если вы ошиблись, вы просто получите ClassCastException, когда попытаетесь использовать ваши данные. Когда входные данные имеют форму:
A=B,C,D
или же
A=B,C,D;W=X,Y,Z
… тогда тип — Map <String, List <String >>, где ключи — это A и W, а их соответствующие значения — B, C, D и X, Y, Z.
Следовательно, учитывая URI выше, аргумент карты будет содержать ….
{BT.A=[276.70, +10.40, +3.91], AZN=[236.00, +103.00, +3.29], SBRY=[375.50, +7.60, +2]}
С этим немного покончено, остальная часть метода очень прямолинейна, поскольку просто преобразует входную карту в список и добавляет ее в модель для отображения JSP (здесь не показано). Обратите внимание, что это не очень полезный код, поэтому не обращайте на него особого внимания, и, кроме того, я не люблю встраивать коллекции в коллекции — это не очень хорошая идея.
Двигаясь дальше, я сейчас посмотрю на следующий URI. Обратите внимание, что я намеренно сделал это похожим на первый, с единственным отличием — добавление данных учетной записи пользователя:
http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.90,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07/account;name=roger;number=105;location=stoke-on-trent,uk
Этот URI сопоставлен следующему методу:
@RequestMapping(value = "/{stocks}/{account}", method = RequestMethod.GET) public String showPortfolioValuesWithAccountInfo(@MatrixVariable(pathVar = "stocks") Map<String, List<String>> stocks, @MatrixVariable(pathVar = "account") Map<String, List<String>> accounts, Model model) { List<List<String>> stocksView = map2List(stocks); model.addAttribute("stocks", stocksView); List<List<String>> accountDetails = map2List(accounts); model.addAttribute("accountDetails", accountDetails); return "stocks"; }
В этом случае полное описание пути — / matrixvars / {stocks} / {account}. Я предполагаю, что это просто говорит Spring искать / matrixvars, за которым следует ‘/’, за которым следует что-либо, за которым следует ‘/’, а затем что-нибудь, когда он выполняет свое отображение.
В этом случае есть две аннотации @MatrixVariable, к которым я добавил аргумент pathVar аннотации, предоставляющий значения акций и счетов. Они аккуратно обозначают, где значения переменных матрицы нужно вводить в аргументы метода.
И последний момент, о котором следует помнить, это то, что переменные матрицы очень гибкие есть еще три аргумента к аннотации @MatrixVaraible, которые я здесь не рассматривал; тем не менее, общая процедура одинакова в каждом случае: возьмите URI, выясните, каковы различные матричные переменные, спроектируйте обработчик запроса и сопоставьте матричные переменные URI с аргументами ваших методов — заботясь о том, чтобы вы получили тип аргумента верный.
Полный пример кода для этого блога доступен на Github: https://github.com/roghughe/captaindebug/tree/master/spring-3.2