【问题标题】:How to add Location header to the http response?如何将 Location 标头添加到 http 响应?
【发布时间】:2021-02-17 08:30:15
【问题描述】:

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

当我收到创建新对象(例如帐户)的请求时,我还想返回带有新创建对象的 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));
    }
    
}

【问题讨论】:

    标签: java spring servlets http-headers servlet-filters


    【解决方案1】:

    我在这里找到了解决方案 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;
        }
    

    【讨论】:

      【解决方案2】:

      很简单,直接传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 ....
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-13
        • 2021-09-23
        • 1970-01-01
        • 1970-01-01
        • 2015-07-19
        • 1970-01-01
        • 2022-01-06
        • 2014-11-03
        • 1970-01-01
        相关资源
        最近更新 更多