rg.apache.jasper.JasperException: <h3>Validation error messages from TagLibraryValidator for c in /jstl.jsp</h3><p>12: Illegal scope attribute without var in "c:set" tag.</p>
...
Ou seja, o atributo scope só funciona junto com o atributo “var” e não com “target”.
Alterar o escopo não, mas alterar uma variavel de determinado escopo faz sentido, é exatamente o que <c:set var> faz, se tem uma variavel no escopo é substituída, não vejo o real motivo de <c:set target> não ter scope. Ou estou perdendo algo aí no conceito…
Vamos supor que haja uma variável “foo” no request e uma “foo” no session.
Se você setar com <c:set var=“foo” blablabla/>, então eve vai colocar a variável naquele escopo não importando se já existia uma outra no lugar.
<c:set var=“foo” scope=“session” var="${requestScope.foo}"/> por exemplo, cria uma variável foo no session com o valor da variável foo do request. Apesar de ter o mesmo nome, são variáveis diferentes.
Mas, no target isso não ocorre, pois o scope é o escopo onde a variável vai ser COLOCADA e não de onde ela vai ser lida. Deste forma, <c:set target="${requestScope.foo}" value=“xxx” scope=“session”/> Tentaria pegar a variável foo do request e colocá-la no session com o valor xxx. Mas isso implica em criar uma nova variável e não setar ela. (se o requestScope for omitido acaba dando na mesma porque o container vai tentar procurar a variável do menor para o maior escopo até encontrar, mas seja lá em qual for o escopo que ele a encontre, a variável não pode ser colocada em um escopo diferente).
E por sinal, mudar o escopo de uma variável é absurdo. Este exemplo mostra que se isso fosse possível, haveriam efeitos colaterais muito estranhos:
No segundo c:out, a variável misteriosamente teria mudado de escopo como efeito colateral de ter recebido um novo valor, algo que é no mínimo indesejável.
A idéia de <c:set> com “target” é somente mudar o valor de uma variável que já existe, não importando qual “scope”. Se o valor de target calcular pra null dá erro…
Já <c:set> com “var” pode criar variáveis caso não exista no escopo definido, sobrescrever o seu valor, ou ainda excluir do escopo caso o atributo já exista no escopo, passando um valor null em “value”.