【问题标题】:Getting 406 Could not find acceptable representation /Spring JSON Test. How to ignore .htm extension in tests?获取 406 找不到可接受的表示 /Spring JSON 测试。如何在测试中忽略 .htm 扩展名?
【发布时间】:2018-07-17 21:45:35
【问题描述】:

控制器需要为所有处理程序使用 .htm 扩展名,包括 JSON REST 端点。我应该如何测试 REST 端点?

问题: 我无法禁用后缀解释,我收到 406“找不到可接受的表示”

尝试过的尝试: 我查看了有关 406 的 stackoverflow 帖子,但找不到与在测试中使用“htm”后缀的情况相关的帖子。当您从 Controller 和 Test 中删除“.htm”后缀时 - 测试通过了。

这里是带有 /changePassword.htm 端点的控制器:

@Controller
public class MainController {

    public static class ResultBean {

        private final String result;

        public String getResult() {
            return result;
        }


        public ResultBean(String result) {
            this.result = result;
        }
    }   

    @RequestMapping(value="/changePassword.htm", method= RequestMethod.POST, produces = { "application/json" }) 
    public @ResponseBody ResultBean changePassword (
            @RequestParam("username") String username, @RequestParam("password") String password) {

        return new ResultBean("OK");
    }
}

这里是配置测试:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { HomeControllerTest.Config.class })
public class HomeControllerTest {

    @InjectMocks
    private MainController controller = new MainController();

    private MockMvc mvc;

    @Configuration
    @EnableWebMvc
    public static class Config extends WebMvcConfigurerAdapter  {

          @Override
          public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.favorPathExtension(false)
                    .favorParameter(true)
                    .parameterName("mediaType")
                    .ignoreUnknownPathExtensions(true)
                    .ignoreAcceptHeader(false)
                    .useJaf(false)
                    .defaultContentType(MediaType.APPLICATION_JSON);
          }

          @Override
          public void configurePathMatch(PathMatchConfigurer configurer) {
              configurer.setUseSuffixPatternMatch(false);
          }       
    }

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mvc = MockMvcBuilders.standaloneSetup(controller)
                .build();
    }

    @Test
    public void shouldPassChangePasswordBean() throws Exception {
        mvc.perform(post("/changePassword.htm")
                .accept("*/*")
                .param("username", "example")
                .param("password", "abcdef")                
                )
            .andExpect(status().isOk()); // Test produces 406 instead of 200
    }
}

有什么想法吗?

【问题讨论】:

    标签: java spring spring-mvc content-negotiation


    【解决方案1】:

    在较新版本的 Spring(我认为是 4+)上,mime 类型首先从后缀确定。

    所以如果你使用.htm 后缀,即使你不想,Spring 也会默认生成 HTML。

    绕过此问题的一种方法是使用重写 URL 的过滤器。比如tuckey URL rewriter filter

    有了这个,你可以设置一些规则,比如:

    /my/page/that/return/json.htm被重写为/my/page/that/return/json,这样Spring就可以根据Accept header产生数据了。

    【讨论】:

      【解决方案2】:

      在 Spring 5 中,尝试将 Web 服务的 URL 更改为 .json!这是正确的解决方法。这里有很多细节http://stick2code.blogspot.com/2014/03/solved-orgspringframeworkwebhttpmediaty.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-21
        • 2013-04-26
        • 1970-01-01
        • 2016-03-11
        • 2019-03-30
        • 2011-11-19
        相关资源
        最近更新 更多