繁体   English   中英

如何将位置标头添加到 http 响应?

[英]How to add Location header to the http response?

我有一个 Java 项目,我正在使用 Servlet 来处理 http 请求。 我也用弹簧

当我收到创建新对象(例如帐户)的请求时,我还想返回带有新创建对象的 GET URL 的“位置”标头。 例如:位置:/accounts/1000

我知道标题已添加到 Servlet 过滤器中(如果我错了,请纠正我)

public class ApiLogFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger("apilogger");

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = ((HttpServletResponse) servletResponse);
       
        httpServletResponse.addHeader( "Location","the location value");
        
        try {
          
            filterChain.doFilter(servletRequest, servletResponse);
          
        } finally {
            String queryString = httpServletRequest.getQueryString() != null ? httpServletRequest.getQueryString() : "N/A";
            String logMessage = "URL: " + httpServletRequest.getRequestURL() + ", Query String: " + queryString + ", Response Status: " + httpServletResponse.getStatus() ;
            LOGGER.info(logMessage);
        }
    }

    @Override
    public void destroy() {

    }
}

但我不明白如何从 API 获取位置值

@RequestMapping("/accounts")
public class IgnoreRuleController {

    private AccountService accountService;

    public void setIgnoreRuleService(IgnoreRuleService ignoreRuleService) {
        this.accountService = ignoreRuleService;
    }

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public String createAccount(@RequestBody Account account) {
        return new Gson().toJson(accountService.createAccount(account));
    }
    
}

我在这里找到了解决方案http://learningviacode.blogspot.com/2013/07/post-with-location.html

你不需要对过滤器做任何事情。 在 api 本身中:

  @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> createIgnoreRule(@RequestBody IgnoreRule ignoreRule) {
        String response = new Gson().toJson(ignoreRuleService.createIgnoreRule(ignoreRule));

        final URI location = ServletUriComponentsBuilder
                .fromCurrentServletMapping().path("/ignore_rules/{id}").build()
                .expand(ignoreRule.getId()).toUri();

        final HttpHeaders headers = new HttpHeaders();
        headers.setLocation(location);


        final ResponseEntity<String> entity = new ResponseEntity<>(response, headers, HttpStatus.CREATED);
        return entity;
    }

很简单,你可以通过header直接抛出你的方法签名:

@RequestMapping(value="/create-account", method = RequestMethod.POST)
@ResponseBody
public String createAccount(@RequestHeader HttpHeaders httpHeader, @RequestBody Account account) {
    var s = httpHeader.get("Location");

    System.out.println(s.get(0));
    return ...
}

实际上,您还可以传递包含所有内容(标题、正文...)的整个请求:

@RequestMapping(value="/create-account", method = RequestMethod.POST)
@ResponseBody
public String createAccount(HttpServletRequest httpRequest, @RequestBody Account account) {
    var s = httpRequest.getHeader("Location");

    System.out.println(s);

    return ....
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM