Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Problema com s:mvcUrl - o que fazer?

Eu encontrei o meu problema em um outro tópico: https://cursos.alura.com.br/forum/topico-problema-com-s-mvcurl-101088 porém, não entendi a solução.

Nesse tópico, o Otávio Felipe envia um link que contém a solução: https://github.com/spring-projects/spring-security/issues/4214 Aparentemente isso é um erro que não foi resolvido do Spring Security.

1- No link que o Otávio enviou, o usuário disse que criou um método (abaixo) para resolver temporariamente esse problema. Porém, em que parte dos meus códigos eu devo colocar esse método? E como faria para usar na JSP? Realmente estou perdido.

public static MethodArgumentBuilder fromMappingName(String name){
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    HttpServletRequest servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();

    UrlPathHelper pathHelper = new UrlPathHelper();
    UriComponentsBuilder baseUri = UriComponentsBuilder.fromPath(pathHelper.getOriginatingContextPath(servletRequest));
    baseUri.path(pathHelper.getOriginatingServletPath(servletRequest));

    return MvcUriComponentsBuilder.fromMappingName(baseUri, name);
}

2- O Otávio também disse para montar a URL sem o uso do mvcUrl. Como eu faço isso com métodos que precisam de parâmetros? Para exemplificar, segue o código que estou tendo problema:

<form action="${s:mvcUrl('CCC#remover').arg(0,item.produto.id).arg(1, item.tipoPreco).build()}" method="POST">

Como vocês podem perceber, eu preciso passar dois parâmetros para o método Remover do Controller CCC(CarrinhoComprasController). Como eu faço isso sem utilizar o mvcUrl?


Obrigado pessoal!

2 respostas
solução!

Olá Daniel, tudo bem com você?

Acredito que o ponto principal é que o mvcURL não está fazendo nada mais do que a concatenação para nós, ele observa o método que estamos chamando e cria a url básica do request mapping do método e depois pega os parâmetros que o método espera com o .arg(), então, podemos tranquilamente chegar no mesmo resultado da maneira "tradicional"

Então no exemplo que você deu:

<form action="${s:mvcUrl('CCC#remover').arg(0,item.produto.id).arg(1, item.tipoPreco).build()}" method="POST">

Isso vai gerar uma URL da seguinte maneira:

  • /casadocodigo/carrinho/remover=produtoID&tipoPreco=tipoPreco

Para chegar nessa URL de uma maneira "normal"

<form:form action="/casadocodigo/carrinho/remover?produtoId=${item.produto.id}&tipoPreco=${item.tipoPreco}" method="POST">

Dessa forma teremos a mesma URL, apenas tivemos que ter um pouco mais de trabalho na hora de montar

Bem, a única desvantagem desse método é que não temos os argumentos de forma dinámica, então as alterações na maneira de fazer o método, ou nome dos parâmetros esperados devem obrigatoriamente gerar uma mudança na .jsp, óbvio que esse é um cenário possível mas que não é tão comum, ficar modificando sem necessidade os nomes ou caminhos dos métodos não é algo bom durante o desenvolvimento, e a adição de parâmetros iria fazer que das duas formas houvessem a necessidade de alterar

A vantagem, pelo menos ao meu ver, é a legibilidade, o mvcUrl na minha opinião deixa a url bem "suja" pois acaba se tornando difícil entender o que está acontecendo, diferente do método criado logo acima :)

Conseguiu Compreender?

Abraços e Bons Estudos!

Olá Geovani, Tudo bom e você?

Agradeço pela sua resposta, esclareceu o problema para mim. Ontem eu consegui chegar em uma solução, porém, não muito amigável. Eu criei dois inputs do tipo hidden e passei os parâmetros.

O problema é que o parâmetro precisa ser String. Como eu preciso do item.produto.id como Integer, tive que fazer dois parse, o primeiro para a JSP enviar como String e o segundo no Controller para transformar em Integer novamente.

<form:form action="/casadocodigo/carrinho/remover" method="POST">
        <c:set var="produtoId" value="${item.produto.id}" />
        <input type="hidden" name="idProduto" value="${item.produto.id}"/>
        <input type="hidden" name="tipoPreco" value="${item.tipoPreco}" />
        <input type="image" src="${contextPath }/resources/imagens/excluir.png" 
        alt="Excluir" title="Excluir" />
</form:form>

Porém, já alterei para o seu código que na minha opinião ficou melhor. Obrigado!!