简体   繁体   English

404 HttpErrorResponse 由于通过 ngForm 从 angular 发送 object 到 springboot

[英]404 HttpErrorResponse due to sending an object via ngForm from angular to springboot

I have a problem with sending form data in angular to springboot.我在将 angular 中的表单数据发送到 springboot 时遇到问题。 I want to add donator to database, but when I try to do that I receive 404 not found exception.我想将捐赠者添加到数据库中,但是当我尝试这样做时,我收到 404 not found 异常。 Below is my code: Here is donator service code in springboot:下面是我的代码: 这是 springboot 中的捐赠者服务代码:

public void addDonator(DonatorDTO donatorDTO) throws MailException {
        if (donatorRepository.existsByEmail(donatorDTO.getEmail())) {
            throw new RuntimeException("User with this e-mail already exists in db");
        } else {
            Donator donator = new Donator();
            Company company = companyRepository.findByCompanyName(donatorDTO.getCompanyName()).orElseThrow(() -> new ResourceNotFoundException("Company not found"));
            BloodGroup blood = bloodGroupRepository.findBloodGroupByBloodType(donatorDTO.getBloodGroup()).orElseThrow(() -> new ResourceNotFoundException("Blood group not found"));
            donator.setName(firstLetterToUpperCase(donatorDTO.getName()));
            donator.setSurname(firstLetterToUpperCase(donatorDTO.getSurname()));
            donator.setEmail(donatorDTO.getEmail());
            donator.setMilitaryRank(donatorDTO.getMilitaryRank());
            donator.setCompany(company);
            donator.setBloodGroup(blood);
            blood.setNumberOfDonators(blood.getNumberOfDonators() + 1);
            donator.setNextDonationDate(LocalDate.now());
            donator.setIsCapable(true);
            donatorRepository.save(donator);
            try {
                mailService.helloNotification(donatorDTO);
            } catch (MailException mailException) {
                logger.error("Can't send email with confirmation of addition donator in a database");
                logger.error(mailException.getMessage());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    }

Here is donator controller:这是捐赠者 controller:

@RestController
public class DonatorController {

    DonatorService donatorService;
    MailService mailService;

    public DonatorController(DonatorService donatorService, MailService mailService) {
        this.donatorService = donatorService;
        this.mailService = mailService;
    }

    @PostMapping(value = "/donators")
    public ResponseEntity addDonator(@RequestBody DonatorDTO donatorDTO) {
        donatorService.addDonator(donatorDTO);
        return new ResponseEntity<>(HttpStatus.OK);
    }

Here is my aplication.properties file:这是我的 aplication.properties 文件:

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/krwiodawstwo?createDatabaseIfNotExist=true&serverTimezone=Europe/Warsaw
spring.datasource.username=root
spring.datasource.password=
spring.mail.host=smtp.gmail.com
spring.mail.username=my_email_example
spring.mail.password=my_password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
server.error.include-message=always
jwt.secret=324ijdijasi4dsa@@@as216767
allowed.origin=http://localhost:4200

Angular donator component code: Angular 捐赠者组件代码:

import { DonatorDTO } from './../../models/DonatorDTO';

import { DonatorsService } from './../../services/donator.service';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, NgForm, Validators } from '@angular/forms';

@Component({
  selector: 'app-donators',
  templateUrl: './donators.component.html',
  styleUrls: ['./donators.component.css']
})
export class DonatorsComponent implements OnInit {

  donatorDTO : DonatorDTO = new DonatorDTO();
  constructor(private donatorService: DonatorsService) {
  }
  ngOnInit(): void {

  }

  companies: string [] =['companyA', 'companyB'];
  bloodGroups: string [] = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', '0+', '0-'];
  ranks: string [] = ['rankaA', 'rankB'];

  createDonator() {
    console.log(this.donatorDTO);
    this.donatorService.addDonator(this.donatorDTO).subscribe(data => {
      console.log(data)
    })
  }
  
}

Angular component.html code: Angular 组件。html 代码:

<!DOCTYPE html>
<html lang="pl-PL">
<body>
    <div class="container">
        <div class="col-md-6">
            <form #test = "ngForm" (ngSubmit) = "createDonator()" >
                <div class="form-group">
                    <input type="text" class = "form-control" [(ngModel)]="donatorDTO.name"  name="name" placeholder="i.e. John  >
                    <small id="nameHelp" class="form-text text-muted">Name</small>
                </div>
                <div class="form-group">
                    <input type="text" class = "form-control" [(ngModel)]="donatorDTO.surname"  name="surname" placeholder="np. Kowalski"  >
                    <small id="surnameHelp" class="form-text text-muted">Surname</small>
                </div>
                <div class="form-group">
                    <input type="email" class = "form-control" [(ngModel)]="donatorDTO.email"  name="email" placeholder="ex. test@gmail.com" >
                    <small id="emailHelp" class="form-text text-muted">email</small>
                </div>
                <div class="form-group">
               <select class="form-control" [(ngModel)]="donatorDTO.militaryRank" name="militaryRank">
                   <option *ngFor="let rank of ranks" [ngValue]="rank">{{rank}}</option>
               </select>
                <small id="rankHelp" class="form-text text-muted">Ranky</small>
                </div>
                <div class="form-group">
                <select [(ngModel)]="donatorDTO.companyName"  name="company" >
                    <option *ngFor="let cmp of companies" [ngValue]="cmp">{{cmp}}</option>
                </select>
                <small id="companyHelp" class="form-text text-muted">Choose company dawcy</small>
                </div>
                <div class="form-group">
                    <select [(ngModel)]="donatorDTO.bloodGroup" name="bloodGroup" >
                        <option *ngFor="let blood of bloodGroups" [ngValue]="blood">{{blood}}</option>
                    </select>
                </div>
                <div class="form-group">
                    <button class = "btn btn-success"  type="submit">Add to base</button>
                </div>
            </form>
            
        </div>
    </div>
</body>
</html>

Here is DonatorService in angular:这是 angular 中的 DonatorService:

import { DonatorDTO } from '../models/DonatorDTO';
import { HttpHeaders, HttpClient } from "@angular/common/http";
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class DonatorsService {
    private watKrewDonationUrl = "http://localhost:8080/donators";

    constructor(private _http: HttpClient){}

    public addDonator(donatorDTO: DonatorDTO): Observable<DonatorDTO>{
        return this._http.post<DonatorDTO>(this.watKrewDonationUrl, donatorDTO);
    }
}

Here is an error view from web browser这是来自 web 浏览器的错误视图

And here is log from springboot terminal springboot terminal I don't know why*email is not null * when the request approaches to spring boot这是来自springboot终端的日志springboot终端我不知道为什么*电子邮件不是null *当请求接近spring启动时

I had a similar problem when I tried to integrate an API with Angular, the solution for me was to add a configuration class to allow access.当我尝试将 API 与 Angular 集成时遇到了类似的问题,我的解决方案是添加配置 class 以允许访问。

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class WebConfig implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods",
                "ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, Key, Authorization");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    public void init(FilterConfig filterConfig) {
        // not needed
    }

    public void destroy() {
        // not needed
    }

}

I also noticed that in your controller you are creating the method with return "ResponseEntity<>" without a type inside the <> sign, in addition to returning an HTTP response ok, the correct thing in POST cases would be something like:我还注意到,在您的 controller 中,除了返回 HTTP 响应之外,您正在创建带有返回“ResponseEntity<>”的方法,而在 <> 符号内没有类型,正确的事情在 POST 案例中是这样的:

@PostMapping("/donators")
@ResponseStatus(HttpStatus.CREATED) //another way to define a response, without using responseEntity
    public DonatorDTO addDonator(@RequestBody DonatorDTO donatorDTO) {
        return donatorService.addDonator(donatorDTO);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM