404 HttpErrorResponse 由于通过ngForm从角度发送对象到springboot
Posted
技术标签:
【中文标题】404 HttpErrorResponse 由于通过ngForm从角度发送对象到springboot【英文标题】:404 HttpErrorResponse due to sending an object via ngForm from angular to springboot 【发布时间】:2021-12-28 19:50:38 【问题描述】:我在向 springboot 发送 Angular 表单数据时遇到问题。我想将捐赠者添加到数据库,但是当我尝试这样做时,我收到 404 not found 异常。下面是我的代码: 这是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();
这里是捐赠者控制器:
@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);
这是我的 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 捐赠者组件代码:
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 组件 .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>
这是 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
这是来自 springboot 终端的日志 springboot terminal 我不知道为什么 *email 不为空 * 当请求接近 Spring Boot 时
【问题讨论】:
【参考方案1】:我在尝试将 API 与 Angular 集成时遇到了类似的问题,我的解决方案是添加一个配置类以允许访问。
@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
我还注意到,在您的控制器中,您正在创建带有返回“ResponseEntity”的方法,而 符号内没有类型,除了返回 HTTP 响应之外,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);
【讨论】:
不幸的是,使用您的示例代码后仍然是同样的问题以上是关于404 HttpErrorResponse 由于通过ngForm从角度发送对象到springboot的主要内容,如果未能解决你的问题,请参考以下文章
Angular HttpErrorResponse GET 请求
Angular-Spring Boot下载excel文件HttpErrorResponse
从服务器抛出的自定义错误未在客户端的 HttpErrorResponse 中返回
Angular 6: HttpErrorResponse SyntaxError: Unexpected token s in JSON