Angular提交表单对象到SpringBoot后端返回404错误如何解决
Angular提交表单到SpringBoot后端返回404错误排查方案
问题描述
在实现Angular前端表单提交对象到SpringBoot后端,并存入MySQL数据库的功能时,接口请求返回404 Not Found错误。
相关代码
Angular服务代码
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); } }
Angular组件代码
import { DonatorDTO } from './../../models/donatorDTO'; import { DonatorsService } from './../../services/donators.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 { donatorForm: NgForm; constructor(private donatorService: DonatorsService) {} ngOnInit(): void { } donatorDTO: DonatorDTO = new DonatorDTO(); companies: string [] =['1. kompania','2. kompania','3. kompania','4. kompania','5. kompania','6. kompania','7. kompania','8. kompania', '9. kompania','10. kompania','11. kompania','12. kompania','13. kompania','14. kompania','15. kompania','16. kompania', '17. kompania','18. kompania','19. kompania','20. kompania','21. kompania']; bloodGroups: string [] = ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', '0+', '0-']; ranks: string [] = ['szer. pchor.', 'st. szer. pchor.', 'kpr. pchor.', 'st. kpr. pchor.', 'plut. pchor.', 'sierż. pchor.']; createDonator() { console.log(this.donatorDTO); this.donatorService.addDonator(this.donatorDTO).subscribe(data => { console.log(data) }) } }
HTML模板代码
<!DOCTYPE html> <html lang="pl-PL"> <body> <div class="container"> <div class="col-md-6"> <form #donatorForm="ngForm" (ngSubmit) = "createDonator()" > <div class="form-group"> <input type="text" class = "form-control" [(ngModel)]="donatorDTO.name" name="name" placeholder="np. Jan" > <small id="nameHelp" class="form-text text-muted">Podaj imię dawcy</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">Podaj nazwisko dawcy</small> </div> <div class="form-group"> <input type="email" class = "form-control" [(ngModel)]="donatorDTO.email" name="email" placeholder="np. jan.kowalski@wp.pl" > <small id="emailHelp" class="form-text text-muted">Podaj email na którego dawca będzie otrzymywał wiadomości związane z HDK</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">Podaj stopień wojskowy</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">Wybierz pododdział 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">Dodaj dawcę do bazy</button> </div> </form> </div> </div> </body> </html>
前端DonatorDTO模型代码
export class DonatorDTO { name: string; surname: string; email: string; militaryRank: string; companyName: string; bloodGroup: string; }
SpringBoot业务层(Service)代码
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(); } } }
SpringBoot控制层(Controller)代码
@RestController public class DonatorController { private final DonatorService donatorService; private final 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); } }
SpringBoot端DonatorDTO定义
package com.example.watkrew.dto; import com.example.watkrew.entity.BloodGroup; import com.example.watkrew.entity.Company; import com.example.watkrew.entity.Donator; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class DonatorDTO { private String name; private String surname; private String email; private String militaryRank; private String companyName; private String bloodGroup; public DonatorDTO(String name, String surname, String email, String militaryRank, Company company, BloodGroup bloodGroup) { this.name = name; this.surname = surname; this.email = email; this.militaryRank = militaryRank; this.companyName = company.getCompanyName(); this.bloodGroup = bloodGroup.getBloodType(); } }
排查与解决步骤
- 确认SpringBoot服务端口与上下文路径
检查SpringBoot配置文件application.properties或application.yml中的配置:
- 确认
server.port配置值为8080,若端口被占用修改为其他端口,同步修改Angular服务中的请求地址端口 - 确认是否配置了
server.servlet.context-path,如果配置了该属性(例如值为/api),需要把Angular中的请求地址修改为http://localhost:8080/[上下文路径]/donators
- 配置跨域支持
Angular默认运行在4200端口,和后端8080端口属于跨域请求,在DonatorController类上添加@CrossOrigin(origins = "http://localhost:4200")注解,允许前端跨域访问。 - 独立验证后端接口
SpringBoot服务启动后,使用接口测试工具(Postman、Apifox等)直接调用POST接口http://localhost:8080/donators,传入符合格式的JSON参数,确认接口可以正常返回。如果接口本身访问就返回404,检查Controller类是否被Spring扫描到,确认启动类包路径是否包含Controller所在的包。 - 检查Angular依赖导入
确认AppModule中已经导入了HttpClientModule并添加到了imports数组中,未导入该模块会导致HTTP请求异常。
内容的提问来源于stack exchange,提问作者giluwilu7
相关产品推荐
相关产品推荐

