Как это исправить: разрешение [org.springframework.web.httprequestmethodnotsupportedException: метод запроса 'post' не пHtml

Программисты Html
Ответить
Anonymous
 Как это исправить: разрешение [org.springframework.web.httprequestmethodnotsupportedException: метод запроса 'post' не п

Сообщение Anonymous »

У меня есть API Spring Boot Rest, и он работает отлично при тестировании через почтальон - все методы HTTP функционируют, как и ожидалось. Однако, когда я пытаюсь взаимодействовать с API из приложения на стороне клиента, я сталкиваюсь с ошибками как на бэкэнд, так и на фронта. /> Решение [org.springframework.web.httprequestmethodnotsupportedException: метод запроса 'post' не поддерживается]
ошибка Frontend < /strong>
[! [Введите описание изображения здесь] [1]] [1] < /p>


Код: Выделить всё

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/v1/persons")
@CrossOrigin(origins = "http://localhost:4200")
public class PersonController {

@Autowired
private PersonRepository personRepository;

public PersonController(PersonRepository personRepository) {
this.personRepository = personRepository;
}

@RequestMapping(
value = "/api/v1/persons",
produces = "application/json",
consumes = { MediaType.MULTIPART_FORM_DATA_VALUE },
method = RequestMethod.GET)
public ResponseEntity createPerson(
@RequestParam String firstname,
@RequestParam String lastname,
@RequestParam String email,
@RequestParam int age,
@RequestPart(value = "photo", required = false) MultipartFile photo,
@RequestPart(value = "cv", required = false) MultipartFile cv){

try {
Person person = new Person();
person.setFirstname(firstname);
person.setLastname(lastname);
person.setEmail(email);
person.setAge(age);

if (photo != null && !photo.isEmpty()) {
person.setPhoto(photo.getBytes());
}

if (cv != null && !cv.isEmpty()) {
person.setCv(cv.getBytes());
}
System.out.println("Save and upload of the files successfully done");
return ResponseEntity.ok(personRepository.save(person));
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

// Get All Persons
@GetMapping
public List getAllPersons() {
return personRepository.findAll();
}

// Get Person by ID
@GetMapping("/{id}")
public ResponseEntity getPersonById(@PathVariable Long id) {
Optional person = personRepository.findById(id);
return person.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}

// Update Person
@PutMapping("/{id}")
public ResponseEntity updatePerson(
@PathVariable Long id,
@RequestParam String firstname,
@RequestParam String lastname,
@RequestParam String email,
@RequestParam int age,
@RequestParam(value = "photo", required = false) MultipartFile photo,
@RequestParam(value = "cv", required = false) MultipartFile cv) {

Optional existingPerson = personRepository.findById(id);

if (existingPerson.isPresent()) {
Person person = existingPerson.get();
person.setFirstname(firstname);
person.setLastname(lastname);
person.setEmail(email);
person.setAge(age);

try {
if (photo != null && !photo.isEmpty()) {
person.setPhoto(photo.getBytes());
}
if (cv != null && !cv.isEmpty()) {
person.setCv(cv.getBytes());
}
} catch (IOException e) {
System.out.println("There is something going waring: " + e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}

return ResponseEntity.ok(personRepository.save(person));
} else {
return ResponseEntity.notFound().build();
}
}

// Download Person's Photo
@GetMapping("/{id}/photo")
public ResponseEntity  getPersonPhoto(@PathVariable Long id) {
Optional person = personRepository.findById(id);

if (person.isPresent() && person.get().getPhoto() != null) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "image/png")
.body(person.get().getPhoto());
}
return ResponseEntity.notFound().build();
}

// Download Person's CV
@GetMapping("/{id}/cv")
public ResponseEntity getPersonCv(@PathVariable Long id) {
Optional person = personRepository.findById(id);

if (person.isPresent() && person.get().getCv() != null) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "application/pdf")
.body(person.get().getCv());
}
return ResponseEntity.notFound().build();
}

// Delete Person
@DeleteMapping("/{id}")
public ResponseEntity deletePerson(@PathVariable Long id) {
if (personRepository.existsById(id)) {
personRepository.deleteById(id);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}< /code>
< /div>
< /div>
< /p>


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // Disable CSRF
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // Enable CORS
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.POST,"/api/v1/persons/**").permitAll() // Allow all requests to this path
.anyRequest().permitAll() // Allow all requests globally (disable authentication)
);

return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:4200"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}< /code>
< /div>
< /div>
< /p>




4.0.0

org.springframework.boot
spring-boot-starter-parent
3.4.2
  

nl.alexandarabski
person-details
0.0.1-SNAPSHOT
person-details
Person details project for Spring Boot














17



org.springframework.boot
spring-boot-starter-data-jpa


org.springframework.boot
spring-boot-starter-web


org.postgresql
postgresql
runtime


org.springframework.boot
spring-boot-starter-test
test


org.springframework.boot
spring-boot-starter-security






org.springframework.boot
spring-boot-maven-plugin




< /code>
< /div>
< /div>
< /p>


server:
port: 8081

spring:
mvc:
hiddenmethod:
filter:
enabled: true
datasource:
url: jdbc:postgresql://localhost:5333/personsdetails
hikari:
username: sanny
password: sanny13
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true
show-sql: true
servlet:
multipart:
enabled: true
max-file-size: 5MB
max-request-size: 10MB
main:
web-application-type: servlet< /code>
< /div>
< /div>
< /p>


export interface Person {
id?: number;
firstname: string;
lastname: string;
email: string;
age: number;
photo: File | null;
cv: File | null;
}< /code>
< /div>
< /div>
< /p>


import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Person } from './person';

@Injectable({
providedIn: 'root'
})
export class PersonService {
private baseUrl: string = "http://localhost:8081/api/v1/persons";
//headers: HttpHeaders | { [header: string]: string | string[]; } | undefined;

constructor(private _httpClient: HttpClient) { }

fetchAllPersons(): Observable {
return this._httpClient.get(this.baseUrl).pipe(
map((persons: Person[]) => persons.map(person => ({
...person,
photo: person.photo ? `data:image/png;base64,${person.photo}` : null,
cv: person.cv ? `data:application/pdf;base64,${person.cv}` : null
})))
);
}

createPerson(personData: FormData): Observable  {
return this._httpClient.post(`${this.baseUrl}`, personData);
}

updatePerson(personId: number, personData: FormData): Observable {
return this._httpClient.put(`${this.baseUrl} ${personId}`, personData);
}

deletePerson(id: number): Observable {
return this._httpClient.delete(`${this.baseUrl}/${id}`);
}
}< /code>
< /div>
< /div>
< /p>


import { ChangeDetectionStrategy, Component,NgModule, inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogModule, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatIconModule } from '@angular/material/icon';
import { Person } from '../person';
import { PersonService } from '../person.service';
import { CommonModule } from '@angular/common';

import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';

@Component({
selector: 'app-person-form',
imports: [
MatDialogModule,
MatDialogContent,
MatDialogActions,
MatButtonModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
CommonModule,
ReactiveFormsModule,
FormsModule
],
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './person-form.component.html',
styleUrl: './person-form.component.css'
})
export class PersonFormComponent {
personForm: FormGroup;
selectedPhoto: File | null = null;
selectedCv: File | null = null;

readonly dialogRef = inject(MatDialogRef);
data = inject(MAT_DIALOG_DATA);

constructor(private personService: PersonService, private fb: FormBuilder) {
this.personForm = this.fb.group({
id: [this.data?.id || null],
firstname: [this.data?.firstname || '', Validators.required],
lastname: [this.data?.lastname || '', Validators.required],
email: [this.data?.email || '', [Validators.required, Validators.email]],
age: [this.data?.age || null, [Validators.required, Validators.min(1)]]
});
}

onFileSelected(event: any, fileType: string) {
const file = event.target.files[0];
if (file) {
if (fileType === 'photo') {
this.selectedPhoto = file;
} else if (fileType === 'cv') {
this.selectedCv = file;
}
}
}

addOrUpdatePerson() {
const formData = new FormData();
formData.append('firstname', this.personForm.value.firstname);
formData.append('lastname', this.personForm.value.lastname);
formData.append('email', this.personForm.value.email);
formData.append('age', String(this.personForm.value.age)); // Convert age to string

if (this.selectedPhoto) {
formData.append('photo', this.selectedPhoto);
}

if (this.selectedCv) {
formData.append('cv', this.selectedCv);
}

if (this.personForm.value.id) {
// Update existing person (PUT)
this.personService.updatePerson(this.personForm.value.id, formData).subscribe({
next: (response) => {
console.log('Person updated successfully', response);
this.dialogRef.close(response); // Close the dialog with updated data
},
error: (error) => console.error('Error updating person:', error)
});
} else {
// Create new person (POST)
this.personService.createPerson(formData).subscribe({
next: (response) => {
console.log('Person created successfully', response);
this.dialogRef.close(response); // Close the dialog with new data
},
error: (error) =>  console.error('Error creating person:', error)
});
}
}
}< /code>
< /div>
< /div>
< /p>


import { Component, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { MatCardModule } from '@angular/material/card';
import { Person } from '../person';
import { PersonService } from '../person.service';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { MatSort, MatSortModule } from '@angular/material/sort';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { PersonFormComponent } from '../person-form/person-form.component';

@Component({
selector: 'app-home',
imports: [
MatFormFieldModule, MatInputModule, MatButtonModule, MatTableModule,
MatCardModule, CommonModule, MatSortModule, MatPaginatorModule, MatDialogModule
],
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent implements AfterViewInit {
person: Person = {  // ✅ Add this property
id: 0,
firstname: '',
lastname: '',
email: '',
age: 0,
photo: null,
cv: null
};

displayedColumns: string[] = ['id', 'firstname', 'lastname', 'email', 'age', 'photo', 'cv', 'edit', 'delete'];
dataSource = new MatTableDataSource();
persons: Person[] = [];
filteredPersons: Person[] = [];
readonly dialog = inject(MatDialog);

@ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatPaginator) paginator!: MatPaginator;

constructor(private personService: PersonService, private sanitizer: DomSanitizer) {}

ngAfterViewInit(): void {
this.loadPersons();
}

loadPersons(): void {
this.personService.fetchAllPersons().subscribe((data) => {
this.persons = data;
this.dataSource = new MatTableDataSource(this.persons);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
});
}

searchPerson(input: string): void {
this.filteredPersons = this.persons.filter(item =>
item.firstname.toLowerCase().includes(input.toLowerCase()) ||
item.lastname.toLowerCase().includes(input.toLowerCase()) ||
item.email.toLowerCase().includes(input.toLowerCase()) ||
item.age.toString().includes(input)
);
this.dataSource = new MatTableDataSource(this.filteredPersons);
}

openDialog(person?: Person): void {
const dialogRef = this.dialog.open(PersonFormComponent, {
data: person
});

dialogRef.afterClosed().subscribe(result => {
if (result) {
this.loadPersons();
}
});
}

deletePerson(id: number): void {
const isConfirmed = window.confirm('Are you sure you want to delete?');
if (isConfirmed) {
this.personService.deletePerson(id).subscribe(() => {
this.persons = this.persons.filter(item => item.id !== id);
this.dataSource.data = this.persons;
});
}
}
}< /code>
< /div>
< /div>
< /p>





Close


Person Form























Upload Photo



Upload CV





Submit
Cancel

< /code>
< /div>
< /div>
< /p>




Full Stack wiht Angular 19, SpringBoot and Docker[/b]




Add +





 Id 
 {{person.id}} 




 First Name 
 {{person.firstname}} 




 Last Name 
 {{person.lastname}} 




 Email 
 {{person.email}} 




 Age 
  {{person.age}} 




 Photo 








 CV 


Download CV






 Edit 
 Edit 



 Delete 
 Delete 











Подробнее здесь: https://stackoverflow.com/questions/794 ... tsupported
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Html»