如何使用 Spring 异常处理 POST REST 更正错误状态代码

Posted

技术标签:

【中文标题】如何使用 Spring 异常处理 POST REST 更正错误状态代码【英文标题】:How to POST REST correct error status code using Spring Exception handling 【发布时间】:2016-11-18 04:32:40 【问题描述】:

我正在尝试处理 POST 请求中丢失的 json 数据。 我的控制器类

@Controller
@RequestMapping("/testMetrics")

public class TestMetricsEndPoint extends StatusEndpointHandler implements RestEndPoint<TestMetrics,String> 

@Autowired
private ObjectMapper mapper;

@Autowired
private TestMetricsService testMetricsService;

@Override
public Status get(String id) 
    // TODO Auto-generated method stub
    return null;



@Override
@RequestMapping(method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
public @ResponseBody Status create(@RequestBody TestMetrics core, BindingResult bindingResult) 
    try 
    if(bindingResult.hasErrors())
        throw new InvalidRequestException("Add failed, Please try again ", bindingResult);
    
    if((core.getGroupName()==""||core.getGroupName()==null)&&(core.getTestName()==null||core.getTestName()==""))

            throw new MissingParametersException(HttpStatus.BAD_REQUEST.value(),"Please provide all necessary parameters");
         
    TestMetrics dataObject = testMetricsService.create(core);
    return response(HttpStatus.CREATED.value(),dataObject);
    catch (MissingParametersException e) 
        return             response(HttpStatus.BAD_REQUEST.value(),e.getLocalizedMessage());
    


扩展类:

public class StatusEndpointHandler 


public Status response(Integer statusCode,Object data)
    Status status = new Status();
    status.setData(data);
    status.setStatus(statusCode);



    return status;



实现的接口:

 public interface RestEndPoint<T extends SynRestBaseJSON, ID extends    Serializable> 

Status get(ID id);

Status create(T entity, BindingResult bindingResult);

结果:

请看高亮部分 因此,当我尝试通过 POSTMAN 测试结果时,我的状态为 200 OK。我不知道如何解决它。请帮我解决这种情况。如何获得正确的状态码。?

【问题讨论】:

【参考方案1】:

您应该将返回类型从 @ResponseBody 更改为 ResponseEntity,这将允许您操作标头,因此设置状态,这是来自文档的 sn-p

 @RequestMapping("/handle")
 public ResponseEntity<String> handle() 
   URI location = ...;
   HttpHeaders responseHeaders = new HttpHeaders();
   responseHeaders.setLocation(location);
   responseHeaders.set("MyResponseHeader", "MyValue");
   return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
 

【讨论】:

对不起,我不清楚你说的。我知道我需要使用@ResponseEntity。但是,我不知道如何使用它。 我几乎暗示这是正确的方法。您应该找到大量资源来了解原因以及如何使用它。基本上,它的内置类在逻辑上等同于您的StatusEndpointHandler【参考方案2】:

在你的catch语句中,尝试通过

设置状态
response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );

Source

【讨论】:

【参考方案3】:

问题在于您的代码处理字符串比较,要比较字符串,您必须使用 equals,来自 Postman,您也传递了空的 testName 和 groupName

    if ((core.getGroupName() == "" || core.getGroupName() == null) && (core.getTestName() == null || core.getTestName() == "")) 
    

所以把你的代码改成下面

    if ((core.getGroupName() == null || core.getGroupName().trim().isEmpty()) && (core.getTestName() == null || core.getTestName().trim().isEmpty())) 

     

也为此写一个ExceptionHandler

@ExceptionHandler( MissingParametersException.class )
public ModelAndView handleException(ServiceException ex, HttpServletResponse response) 
    response.setStatus(HttpStatus.BAD_REQUEST.value());
    ModelMap model = new ModelMap();
    model.addAttribute("message", ex.getMessage());
    return new ModelAndView("error", model);

您也可以使用验证api在实体类中定义验证约束,在这种情况下您需要将@Valid添加到请求模型对象中

@Entity
class TestMetrics 

    @Id
    Long id;

    @NotNull
    @NotEmpty
    @Column
    String groupName;

    @NotNull
    @NotEmpty
    @Column
    String testName;

    // Getters and Setters


【讨论】:

您输入了testNamegroupName 吗?根据验证逻辑,它不应为空或 null 是的。我输入了他们的机器人 您能否在方法create 中发布testNamegroupName 更新了带有异常处理程序的代码,看看吧

以上是关于如何使用 Spring 异常处理 POST REST 更正错误状态代码的主要内容,如果未能解决你的问题,请参考以下文章

DAY8 - 异常处理,面向对象编程

Spring cloud Zuul网关异常处理

Spring MVC异常处理

Spring学习日志二

面试官:如何使用 Spring Boot 实现异常处理?

异常处理