#spring #spring-boot
#spring #spring-boot
Вопрос:
Я использую Angular CLI и Spring Boot.
Все работает (getEmployee, deleteEmployee), но когда я хочу обновить или создать (тем же методом и той же HTML-формой) сотрудника, я получаю в HTML Console / Network эту ошибку:
[ERROR] message: "Request method 'PUT' not supported"
Это мой контроллер:
@RestController
@RequestMapping("/api")
public class EmployeeController {
private final EmployeeServiceImpl employeeService;
@Autowired
public EmployeeController(EmployeeServiceImpl employeeService) {
this.employeeService = employeeService;
}
@GetMapping("/employees")
public List<Employee> getAllEmployees() {
return employeeService.findAllEmployees();
}
@GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId) {
Employee employee = employeeService.findById(employeeId).get();
return ResponseEntity.ok().body(employee);
}
@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
@Valid @RequestBody Employee employeeDetails) {
Employee employee = employeeService.findById(employeeId).get();
employee.setEmailAddress(employeeDetails.getEmailAddress());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
employee.setStatus(employeeDetails.getStatus());
employee.setSkills(employeeDetails.getSkills());
final Employee updatedEmployee = employeeService.saveEmployee(employee);
return ResponseEntity.ok(updatedEmployee);
}
@DeleteMapping("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId) {
Employee employee = employeeService.findById(employeeId).get();
employeeService.deleteEmployee(employee);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}//close class
Это также мой CORSConfig:
@Configuration
public class CORSConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedHeaders("*")
.allowedMethods("GET", "POST", "DELETE","PUT");
}
}//close class
Здесь вы можете увидеть мой код Angular:
EmployeeDetail.ts
export class EmployeeDetailsComponent implements OnInit {
@Input()
employee: Employee;
skills;
constructor(
private route: ActivatedRoute, /* holds information about the route to this instance of the EmployeeDetailsComponent */
private location: Location,
private employeeService: EmployeeService,
private skillService: SkillService
) {
}
ngOnInit() {
this.getEmployee();
this.skillService.getSkills().subscribe(res => this.skills = res);
}
getEmployee(): void {
const id = this.route.snapshot.paramMap.get('id');
if (id === -1) {
this.employee = new Employee();
} else {
this.employeeService.getEmployee(id)
.subscribe(employee => this.employee = employee);
}
}
save(): void {
this.employeeService.updateEmployee(this.employee)
.subscribe(() => this.goBack());
console.log('test', this.employee);
}
goBack(): void {
this.location.back();
}
}
Когда я нажимаю «Сохранить», метод перенаправляет меня на метод обновления в моем сервисе;
service.ts
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
@Injectable({
providedIn: 'root'
})
export class EmployeeService {
private baseUrl = 'http://localhost:8080/api/employees';
constructor(private http: HttpClient) { }
/** GET Employees from the server */
getEmployees(): Observable<Employee[]> {
return this.http.get<Employee[]>(this.baseUrl);
}
getEmployee(id: number): Observable<Employee> {
const url = this.baseUrl '/' id;
return this.http.get<Employee>(url);
}
/** PUT: update the employee on the server */
updateEmployee(employee: Employee): Observable<any> {
return this.http.put(this.baseUrl, employee, httpOptions);
}
deleteEmployee(id: number): Observable<any> {
return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
}
}
Это мое первое приложение SpringBoot, также с Angular, поэтому я никогда раньше не видел этой ошибки.
Что я могу сделать?
Комментарии:
1. обновите свой метод addCorsMappings с помощью . Разрешенные методы (» * «) .Разрешенные исходные данные(» * «)
2. вот так? общедоступные пустые добавления corsmappings(реестр CorsRegistry) { registry.addMapping(«/**»).allowedHeaders(«*») .allowedMethods(«* «) .allowedOrigins(» * «);
3. можете ли вы опубликовать свой угловой код о том, как вы делаете запрос put?
4.
@Configuration public class CORSConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedHeaders("*").allowedMethods("*") .allowedOrigins("*"); } }
5. Похоже, что ваш код angular отправляет запрос в / api /employees, но сопоставление в коде spring — /api/employees /{id}.
Ответ №1:
Ваш код Angular показывает следующий метод
updateEmployee(employee: Employee): Observable<any> {
return this.http.put(this.baseUrl, employee, httpOptions);
}
Вы не указали id в angular side. Но для вашей стороны spring boot требуется идентификатор. Поскольку вы не передаете идентификатор, фреймворк не может найти соответствующий метод, что приводит к ошибке 405 «метод не разрешен»
@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
@Valid @RequestBody Employee employeeDetails) {
Employee employee = employeeService.findById(employeeId).get();
employee.setEmailAddress(employeeDetails.getEmailAddress());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
employee.setStatus(employeeDetails.getStatus());
employee.setSkills(employeeDetails.getSkills());
final Employee updatedEmployee = employeeService.saveEmployee(employee);
return ResponseEntity.ok(updatedEmployee);
}
Комментарии:
1. Вы можете сделать это так же, как метод delete, или попытаться добавить идентификационные данные внутри объекта employee
2. Хорошо, я отредактировал следующим образом: updateEmployee(employee: Сотрудник): Наблюдаемый<любой> { верните this.http.put(
${this.baseUrl}/${employee.id}
, employee, httpOptions); } Если я редактирую или создаю, я получаю эту ошибку: ошибка: «Ошибка внутреннего сервера» сообщение: «Значение отсутствует» путь: «/ api/ employees / 4» статус: 5003. Редактирование ОБНОВЛЕНИЯ работает хорошо, создайте ошибку 500, как в предыдущем комментарии.
4. какова цель метода create?
5. метод create аналогичен методу update, я понимаю ошибку, идентификатор является автоинкрементным, поэтому мне нужно иметь возможность передавать новый идентификатор, поэтому он может найти нового пользователя. Но я не знаю, почему, когда я создаю нового пользователя, он не генерирует идентификатор. Есть идеи? (Я не устанавливал его в контроллере)