有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring rest controller@ExceptionHandler返回xml内容和json错误

所以我有一个@RestController,我想基于前端应用程序的模式返回和验证XML,以便在编辑器中显示它们。我希望错误是json格式的,以便用js处理和显示它们

@RestController
public class UserController {

    @RequestMapping(value = "/test",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_XML_VALUE)
    public ResponseEntity<String> throwException(
        @RequestParam(value = "flag", defaultValue = "false") Boolean flag
    ) throws Exception {
        if (flag) {
            throw new Exception();
        } else {
            return ResponseEntity.ok("<xml>hello</xml>");
        }
    }


    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(Exception.class)
    @ResponseBody
    ServerError exceptionHandler(HttpServletRequest req, Exception ex) {
        return new ServerError(req.getRequestURL().toString(),ex);
    }

}

我想以JSON格式返回的ServerError:

public class ServerError {

    public final String url;
    public final String error;

    public ServerError(String url, Exception ex) {
        this.url = url;
        this.error = ex.getMessage();
    }

    public String getUrl() {
        return url;
    }

    public String getError() {
        return error;
    }
}

所以<xml>hello</xml>返回得很好,但是当我将标志设置为true时,我得到

ERROR   2017-10-18 12:56:53,189 [http-nio-0.0.0.0-8080-exec-2] org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver  - Failed to invoke @ExceptionHandler method: eu.openminted.registry.core.exception.ServerError eu.openminted.registry.service.UserController.malformedExeption(javax.servlet.http.HttpServletRequest,java.lang.Exception)
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

此外,将produces同时设置为XML和JSON会产生相同的结果

@RequestMapping(value = "/test",
        method = RequestMethod.GET,
        produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_UTF8_VALUE})

共 (2) 个答案

  1. # 1 楼答案

    通过从@RequestMapping中删除produces并用ResponseEntity指定我想要返回的类型,我成功地解决了这个问题

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ResponseEntity<String> throwException(
        @RequestParam(value = "flag", defaultValue = "false") Boolean flag
    ) throws Exception {
        if (flag) {
            throw new Exception();
        } else {
            ResponseEntity response = ResponseEntity.ok().
                contentType(MediaType.APPLICATION_XML).
                body("<xml>hello</xml>");
            return response;
        }
    }
    

    这个解决方案的问题是,所有方法都有一个@annotation与它们产生的类型相关,而这并没有破坏一致性

  2. # 2 楼答案

    要使ExceptionHandler返回XML格式(默认情况下返回JSON格式),需要执行两个步骤:

    1. 导入maven依赖项:
     <dependency>
         <groupId>com.fasterxml.jackson.dataformat</groupId>
         <artifactId>jackson-dataformat-xml</artifactId>
     </dependency>
    
    1. 使用ResposneEntity的静态方法internalServerError()ResponseEntity.internalServerError().header("MyHeader","MyValue").contentType(MediaType.APPLICATION_XML).body(ex);

    在contentType中,指定MediaType.APPLICATION_XML