У меня есть веб-сервис Restful, использующий Spring boot. Ответом является компонент EmployeeResponseData, который весной преобразуется в json. В соответствии с бизнесом веб-служба должна возвращать сведения о сотруднике, когда входной идентификатор сотрудника совпадает, иначе должен быть возвращен ответ json с ошибкой, как показано ниже.
{"Error ": "Employee not not found for empId "+ **empId** }
На данный момент я получаю правильный ответ json в соответствии с bean-компонентом EmployeeResponseData, если входной empId совпадает. Но я становлюсь пустым, если empId не совпадает.
Как я могу вернуть JSON с желаемой ошибкой в случае настраиваемого исключения, без необходимости формировать json и возвращать вместо использования beans в качестве возвращаемого объекта, поскольку он автоматически преобразуется в jSON с помощью Spring.
Ниже приведен код.
Бобы
EmployeeRequestData
package com.beans;
import org.springframework.stereotype.Component;
@Component
public class EmployeeRequestData {
private int EmpoyeeId;
public int getEmpoyeeId() {
return EmpoyeeId;
}
public void setEmpoyeeId(int empoyeeId) {
EmpoyeeId = empoyeeId;
}
}
EmployeeResponseData
package com.beans;
import java.util.ArrayList;
import org.springframework.stereotype.Component;
@Component
public class EmployeeResponseData {
private int employeeId;
private String name;
private String department;
private ArrayList<String> skills;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public ArrayList<String> getSkills() {
return skills;
}
public void setSkills(ArrayList<String> skills) {
this.skills = skills;
}
}
Контроллер
package com.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.beans.EmployeeResponseData;
import com.service.ServiceRequest;
@RestController
public class WebServiceController {
@Autowired
private ServiceRequest serviceRequest;
@RequestMapping(value = "restws/getEmpDetails/{empId}",method=RequestMethod.GET)
//@ResponseBody // not required since using @RestController
public EmployeeResponseData getEmployeeDetails(@PathVariable("empId") int empId) {
return serviceRequest.getEmployeeDetails(empId);
}
}
Услуга
package com.service;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.beans.EmployeeResponseData;
import com.exception.EmployeeNotFoundException;
@Service
public class ServiceRequest {
private static Logger LOGGER = LoggerFactory.getLogger(ServiceRequest.class);
@Autowired
private EmployeeResponseData employeeResponseData;
public EmployeeResponseData getEmployeeDetails(int empId) {
ArrayList<String> employeeSkills = (ArrayList<String>) Stream.of("Core Java"
,"Restful web services"
,"Spring Boot"
,"PLSQL").collect(Collectors.toList());
employeeResponseData.setEmployeeId(empId);
employeeResponseData.setName("Priyanjan Kumar");
employeeResponseData.setDepartment("ENGNE");
employeeResponseData.setSkills(employeeSkills);
}else {
try {
throw new EmployeeNotFoundException(empId);
} catch (EmployeeNotFoundException e) {
LOGGER.info("Employee data not found for empId :"+empId);
}
}
return employeeResponseData;
}
}
Пользовательское исключение
package com.exception;
public class EmployeeNotFoundException extends Exception{
private String message = "Employee not found";
public EmployeeNotFoundException() {
// super(message); it takes only static variable
}
public EmployeeNotFoundException(int empId) {
message = message+" for Employee : "+ Integer.toString(empId);
}
@Override
public String toString() {
return message;
}
}
SpringBootApplication
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}





Сначала напишите класс POJO с именем ApiErrorReponse.java.
public class ApiErrorResponse{
private final String error;
//Any addtional info you might later want to add to it
public ApiErrorResponse(String error){
this.error = error;
}
public String getError(){
return this.error;
}
}
Теперь в вашем контроллере измените конечную точку на.
@RequestMapping(value = "restws/getEmpDetails/{empId}",method=RequestMethod.GET)
public ResponseEntity<?> getEmployeeDetails(@PathVariable("empId") int empId) {
EmployeeResponseData data = serviceRequest.getEmployeeDetails(empId);
if (data != null){
return new ResponseEntity<EmployeeResponseData>(data, HttpStatus.OK);
}
ApiErrorResponse errorReponseDto = new ApiErrorResponse("Employee not not found for empId "+ empId);
return new ResponseEntity<ApiErrorResponse>(errorReponseDto, HttpStatus.NOT_FOUND);
}
Возможно, вы захотите улучшить основы, ваш класс обслуживания плохо написан и может работать не всегда.
РЕДАКТИРОВАТЬ
Итак, согласно вашему комментарию, вы можете генерировать исключения в своем классе обслуживания и в вашем контроллере, перехватывать эти исключения и возвращать сообщение об исключении в качестве ответа об ошибке.
@RequestMapping(value = "restws/getEmpDetails/{empId}",method=RequestMethod.GET)
public ResponseEntity<?> getEmployeeDetails(@PathVariable("empId") int empId) {
try{
EmployeeResponseData data = serviceRequest.getEmployeeDetails(empId);
return new ResponseEntity<EmployeeResponseData>(data, HttpStatus.OK);
}
catch(Exception ex){
ApiErrorResponse errorReponseDto = new ApiErrorResponse(ex.getMessage());
return new ResponseEntity<ApiErrorResponse>(errorReponseDto, HttpStatus.NOT_FOUND);
}
}
Вы можете использовать аннотацию @ControllerAdvice для обработки различных типов исключений, возникающих в приложении.
Ниже приведен пример кода, как это выглядит:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(EmployeeNotFoundException.class)
public ResponseEntity<String> handleEntityNotFoundException(HttpServletRequest request, Exception ex) {
return ResponseUtil.buildErrorResponseEntity(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGenericException(HttpServletRequest request, Exception ex) {
return ResponseUtil.buildErrorResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
Вы можете написать метод для создания сообщений об ошибках в соответствии с вашими требованиями.
Кроме того, вам нужно добавить объявление исключения throws в свой контроллер следующим образом:
public EmployeeResponseData getEmployeeDetails(@PathVariable("empId") int empId) throws Exception {
return serviceRequest.getEmployeeDetails(empId);
}
Возможно, вам придется переписать логику вашего класса обслуживания, чтобы получить данные из какого-либо ресурса или БД, и на основе результата вы можете создать ответ bean-компонента в случае успеха или соответственно сгенерировать исключение.
public EmployeeResponseData getEmployeeDetails(int empId) {
// Get data from resource/DB based on empId
EmployeeResponseData employeeResponseData = new EmployeeResponseData();
if (data != null) {
ArrayList<String> employeeSkills = (ArrayList<String>) Stream.of("Core Java"
,"Restful web services"
,"Spring Boot"
,"PLSQL").collect(Collectors.toList());
employeeResponseData.setEmployeeId(empId);
employeeResponseData.setName("Priyanjan Kumar");
employeeResponseData.setDepartment("ENGNE");
employeeResponseData.setSkills(employeeSkills);
} else {
throw new EmployeeNotFoundException(empId);
}
}
return employeeResponseData;
}
Я получаю ошибку компиляции, говоря, что ResponseUtil не может быть разрешен в классе RestExceptionHandler. Мне нужно добавить для этого дополнительную зависимость?
Это настраиваемый класс, который может быть написан вами для обработки различных типов ответов, таких как успешный ответ и ответ об ошибке. Я просто привел пример.
Спасибо за ответ. Это почти то, что я хочу. Но вместо установки ошибки в контроллере я хочу установить ошибку в классе обслуживания, поэтому, если я установил сообщение об ошибке в классе обслуживания, то как мне получить этот объект ApiErrorResponse, который имеет сообщение об ошибке в контроллере. потому что есть разные случаи ошибок, и кодировать все это в контроллере - не лучшая идея. Также данные могут быть не нулевыми, но только мы не можем отправить их в ответ, поскольку запрашивающая сторона не имеет права просматривать данные. Мой класс обслуживания я жестко запрограммировал, чтобы дать только базовую идею.