Sei que posso estar errando em coisa boba, mas já perdi um tempão procurando… Quando clico no botão de editar da lista, sempre dá erro 405 (método não suportado. ‘Method GET is not allowed for requested URI’ ). Fiz as anotações, inclusive na apostila alerta sobre essa possibilidade de erro no uso do GET , POST, etc, mas não acho onde possa estar errando… Já a inserção e a exclusão estão corretas… o erro completo é:
11:24:33,649 DEBUG [DefaultResourceTranslator] trying to access /produtos/1
11:24:33,653 DEBUG [ResourceLookupInterceptor] Method GET is not allowed for requested URI. Allowed Methods are [PUT, DELETE]
br.com.caelum.vraptor.http.route.MethodNotAllowedException: Method GET is not allowed for requested URI. Allowed Methods are [PUT, DELETE]
at br.com.caelum.vraptor.http.route.DefaultRouter.routesMatchingUriAndMethod(DefaultRouter.java:110)
at br.com.caelum.vraptor.http.route.DefaultRouter.parse(DefaultRouter.java:83)
at br.com.caelum.vraptor.http.DefaultResourceTranslator.translate(DefaultResourceTranslator.java:59)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:66)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
11:24:33,655 DEBUG [VRaptor ] VRaptor ended the request
ProdutoController
import java.util.List;
import br.com.caelum.goodbuy.dao.ProdutoDao;
import br.com.caelum.goodbuy.modelo.Produto;
import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;
@Resource
public class ProdutosController {
private final ProdutoDao dao;
private final Result result;
private final Validator validator;
public ProdutosController(ProdutoDao dao, Result result, Validator validator){
this.dao = dao;
this.result = result;
this.validator = validator;
}
@Path("/produtos")
@Get
public List<Produto> lista(){
return dao.listaTudo();
}
@Post
@Path("/produtos")
public void adiciona(final Produto produto){
// Validação pelo Hibernate, pelas anotações do Hibernate no modelo PRODUTO
validator.validate(produto);
validator.onErrorUsePageOf(ProdutosController.class).formulario();
dao.salva(produto);
result.redirectTo(this).lista();
}
@Get
@Path("/produtos/{id}/edita")
public Produto edita(Long id){
return dao.carrega(id);
}
@Put
@Path("/produtos/{produto.id}")
public void altera(Produto produto){
validaForm(produto); //Validação
validator.onErrorUsePageOf(ProdutosController.class).edita(produto.getId()); //informa o destino no erro Edição
dao.atualiza(produto);
result.redirectTo(this).lista();
}
@Delete
@Path("/produtos/{id}")
public void remove(Long id){
Produto produto = dao.carrega(id);
dao.remove(produto);
result.redirectTo(this).lista();
}
// ----- Páginas: Métodos Genéricos
@Get @Path("produtos/novo")
public void formulario(){
}
}
lista.jsp
<table>
<thead>
<tr>
<th>Nome</th>
<th>Descricao</th>
<th>Preço</th>
</tr>
</thead>
<tbody>
<c:forEach items="${produtoList}" var="produto">
<tr>
<td>${produto.nome}</td>
<td>${produto.descricao}</td>
<td>${produto.preco}</td>
<td><a href="<c:url value="/produtos/${produto.id}"/>">Editar</a></td> <!-- trabalhando com anotações do ProdutosController -->
<td>
<form action="<c:url value="/produtos/${produto.id}"/>" method="POST">
<button class="link" name="_method" value="DELETE">Remover</button>
</form>
</td>
</tr>
</c:forEach>
</tbody>
</table>
edita.jsp
<form action="<c:url value="/produtos/${produto.id}"/>" method="POST"> <!-- Trabalhando com as anotações no ProdutoController -->
<fieldset>
<legend>Editar Produto</legend>
<label for="nome">Nome:</label>
<input id="nome" type="text" name="produto.nome" value="${produto.nome}" />
<label for="descricao">Descrição:</label>
<textarea id="descricao" name="produto.descricao">${produto.descricao}</textarea>
<label for="preco">Preço:</label>
<input id="preco" type="text" name="produto.preco" value="${produto.preco}" />
<button type="submit" name="_method" value="PUT">Enviar</button> <!-- Trabalhando com as anotações no ProdutoController -->
</fieldset>
</form>
Obrigado desde já!