22
respostas

status=405

já tentei de tudo quanto foi jeito e não esta funcionando tem algo de errado mas não sei o que é. algem pode me ajudar?

@RestController
@RequestMapping("/api/ofertas")
public class OfertasRest {

    @Autowired
    private PedidoRepository pedidoRepository;

    @PostMapping
    public Oferta criaOferta(@Valid @RequestBody RequisicaoNovaOferta requisicao) {
        Optional<Pedido> pedidoBuscado = pedidoRepository.findById(requisicao.getPedidoId());
        if(!pedidoBuscado.isPresent()) {
            return null;
        }

        Pedido pedido = pedidoBuscado.get();

        Oferta nova = requisicao.toOferta();
        nova.setPedido(pedido);
        pedido.getOfertas().add(nova);
        pedidoRepository.save(pedido);

        return nova;
    }
}

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

22 respostas

Olá! Tudo bem?

No seu código, é possível ver que você está utilizando a anotação "@PostMapping" para permitir apenas requisições POST para o método "criaOferta".

Quando você faz um request no browser é feito uma requisição GET

É por isso que está ocorrendo o error "request method GET not supported"

mas quando mando post ele náo vai. Insira aqui a descrição dessa imagem para ajudar na acessibilidade

<script>
        function onLoad() {
            var app = new Vue({
                el : '#oferta',
                data : {
                    pedidos : []
                },
                mounted () {
                    axios
                        .get('http://localhost:8080/api/pedidos/aguardando')
                        .then(response => {
                            response.data.forEach(pedido =>{
                                pedido.ofertaEnviada = false;
                                pedido.erros = {
                                    valor: '',
                                    dataDaEntrega: ''
                                }    
                            } )
                            this.pedidos = response.data
                        })
                },
                methods: {
                    enviarOferta: function(pedido) {
                            pedido.erros = {
                                  valor: '',
                                  dataDaEntrega: ''
                              };

                        axios
                            .post('http://localhost:8080/api/ofertas', {
                                pedidoId: pedido.id,
                                valor: pedido.valorNegociado,
                                dataDaEntrega: pedido.dataDaEntrega,
                                comentario: pedido.comentario
                            })
                            .then(response => pedido.ofertaEnviada = true)
                            .catch(error => {
                                error.response.data.errors.forEach( error =>{
                                    pedido.erros[error.field] = error.defaultMensage;
                                })
                            })
                    }
                }
            });
        }
    </script>

Oi!

O problema acontece quando o seu código JavaScript dispara a requisição para cadastrar a oferta. Está sendo devolvido o código 403, o que significa que tem algum bloqueio sendo feito pelo Spring Security no seu projeto.

Manda aqui os códigos de configurações de segurança do seu projeto.

package br.com.alura.mvc.mudi;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//import org.springframework.security.core.userdetails.User;
//import org.springframework.security.core.userdetails.UserDetails;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/home/**", "/api/**")
            .permitAll()
        .anyRequest()
            .authenticated()
        .and()
        .formLogin(form -> form
            .loginPage("/login")
            .defaultSuccessUrl("/usuario/pedido", true)
            .permitAll()
        )
        .logout(logout -> {
            logout.logoutUrl("/logout")
                .logoutSuccessUrl("/home");
        });
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

/** 
        UserDetails user =
                 User.builder()
                    .username("marta")
                    .password(encoder.encode("ar2022"))
                    .roles("ADM")
                    .build();
*/
        auth.jdbcAuthentication()
        .dataSource(dataSource)
        .passwordEncoder(encoder);
//        .withUser(user);
    }

}

A princípio está ok.

Deve ter dado exception ao disparar essa requisição. Manda aqui os logs que apareceram no console do Eclipse

Hibernate: select pedido0_.id as id1_1_, pedido0_.data_da_entrega as data_da_2_1_, pedido0_.descricao as descrica3_1_, pedido0_.nome_produto as nome_pro4_1_, pedido0_.status as status5_1_, pedido0_.url_imagem as url_imag6_1_, pedido0_.url_produto as url_prod7_1_, pedido0_.user_username as user_use9_1_, pedido0_.valor_negociado as valor_ne8_1_ from pedido pedido0_ where pedido0_.status=? order by pedido0_.id desc limit ?

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Sobre o erro:

(intermediate value).then is not a function

Como essa linha está dentro do bloco mounted() da instância Vue, pode ser que o problema seja que a biblioteca Axios não foi corretamente importada no arquivo HTML da página. Para corrigir o erro, verifique se o Axios foi importado corretamenteno final do HTML conforme abaixo:

<html>
    <head th:replace="~{base :: head}"></head>
    <body onload="onLoad()">
        <div th:replace="~{base :: logo}"></div>

        <div class="container" id="ofertas">
            <div th:replace="~{base :: titulo('Faça sua Oferta')}"></div>

            <div class="card mb-3" v-for="pedido in pedidos">
                <div class="card-header alert-dark">{{pedido.nomeProduto}}</div>
                <div class="card-body">
                    <div class="row">
                        <div class="col-12 col-sm-8  mb-3">
                            <div>Produto</div>
                            <div> <a v-bind:href="pedido.urlProduto">{{pedido.nomeProduto}}</a></div>

                            <div>Descrição</div>
                            <div>
                                <textarea disabled="disabled" class="form-control">{{pedido.descricao}}</textarea>
                            </div>
                            <div class="row mt-3">
                                <div class="col-md-5">
                                    Valor: <input v-bind:class="{'is-invalid':pedido.erros.valor !==''}" class="form-control" v-model="pedido.valorNegociado"/>
                                    <div v-if="pedido.erros.valor" class="invalid-feedback" >
                                        {{pedido.erros.valor}}
                                    </div>
                                </div>
                                <div class="col-md-7">
                                    Data da entrega: <input v-bind:class="{'is-invalid':pedido.erros.dataDaEntrega !==''}" class="form-control" v-model="pedido.dataDaEntrega"/>
                                    <div v-if="pedido.erros.dataDaEntrega" class="invalid-feedback">
                                        {{pedido.erros.dataDaEntrega}}
                                    </div>
                                </div>
                            </div>
                            <div class="mt-2">
                                <label>Comentário</label>
                                <textarea class="form-control" v-model=pedido.comentario></textarea>
                            </div>
                            <button v-if="pedido.ofertaEnviada" class="btn btn-success mt-2">Oferta Enviada</button>
                            <button v-else v-on:click="enviarOferta(pedido)" class="btn btn-primary mt-2">Enviar Oferta</button>
                        </div>
                        <div class="col-12 col-sm-4">
                            <div>
                                <img class="img-thumbnail" v-bind:src="pedido.urlImagem"/>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script>
            function onLoad() {
                var app = new Vue(
                {
                    el : '#ofertas',
                    data : {
                        pedidos : []
                    },
                    mounted () {
                        axios
                          .get('http://localhost:8080/api/pedidos/aguardando')
                          .then(response => {
                                  response.data.forEach(pedido =>{
                                      pedido.ofertaEnviada = false;
                                      pedido.erros = {
                                          valor: '',
                                          dataDaEntrega: ''
                                      }
                                  })
                                 this.pedidos = response.data
                            })
                    },
                    methods: {
                        enviarOferta: function(pedido) {
                            pedido.erros = {
                                  valor: '',
                                  dataDaEntrega: ''
                              };

                            axios
                              .post('http://localhost:8080/api/ofertas', {
                                  pedidoId: pedido.id,
                                  valor: pedido.valorNegociado,
                                  dataDaEntrega: pedido.dataDaEntrega,
                                  comentario: pedido.comentario
                              })
                              .then(response => pedido.ofertaEnviada = true)
                              .catch(error => {
                                  error.response.data.errors.forEach(error => {
                                      pedido.erros[error.field] = error.defaultMessage;
                                  })
                              })
                        } 
                    }
                });
            }
        </script>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    </body>
</html>

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeCopiei seu erro e de esse erro aqui no lambda do js, agora. Insira aqui a descrição dessa imagem para ajudar na acessibilidade

eu tentei colocar no vscold, no eclipse e nem um deles deu erro no console, o que acho estranho ou pode ser meu código JS.

Consegue compartilhar teu projeto?

vc fala no git? se for consigo sim. ou tem outro local?

pode ser no github mesmo. Sobe o projeto la num repositorio e me manda o link aqui

certo vou colocar hoje a noite, obrigado.

https://github.com/brunoffraga/loja-de-favorito/tree/master

Conforme solicidado esse o link a sima do git. Só um detalhe tem que adicionar um banco conforme o curso.

Está faltando a chamada a esse metodo nas configurações de segurança:

.csrf().disable();

O método deve ficar assim:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/home/**", "/api/**")
            .permitAll()
        .anyRequest()
            .authenticated()
        .and()
        .formLogin(form -> form
            .loginPage("/login")
            .defaultSuccessUrl("/usuario/pedido", true)
            .permitAll()
        )
        .logout(logout -> {
            logout.logoutUrl("/logout")
                .logoutSuccessUrl("/home");
        }).csrf().disable();
    }

agora funcionou, só que não esta passando para o banco de dados.

Precisa avaliar no seu controller OfertasRest se os dados estão chegando certinhos. Coloca um System.out para ver:

@PostMapping
public Oferta criaOferta(@Valid @RequestBody RequisicaoNovaOferta requisicao) {

    System.out.println("\n\n\nDADOS RECEBIDOS: " +requisicao +"\n\n\n");

    Optional<Pedido> pedidoBuscado = pedidoRepository.findById(requisicao.getPedidoId());
    if(!pedidoBuscado.isPresent()) {
        return null;
    }

    Pedido pedido = pedidoBuscado.get();

    Oferta nova = requisicao.toOferta();
    nova.setPedido(pedido);
    pedido.getOfertas().add(nova);
    pedidoRepository.save(pedido);

    return nova;
}

E sobrescreve o método toString na sua classe RequisicaoNovaOferta:

public String toString() {
    return "RequisicaoNovaOferta[pedidoId: " +pedidoId +"; valor: " +valor +"; dataDaEntrega: " +dataDaEntrega +"; comentario: " +comentario +" ]";
}

Cadastrei um produto novo para ver se iria funcionar e funcionou.

Exclui a tabela para ver se iria cria e criou.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Meu erro ainda não foi corrigido aqui ainda.

Oi!

Qual o problema agora? Pelo seu print anterior os dados estão chegando certinhos no controller, exceto o pedidoId, que está chegando como 0