restspring-mvcprotocol-buffers

spring mvc4 http 404 not found


I have seen other similar posts here on stackoverflow - mostly the poster is hitting a link different than what the serving method in the RESTController resolves to. I am making sure (explained below) i am not doing that mistake but still its not working for me..

I am writing a Spring MVC4 based REST controller for a Servlet 2.5 container (weblogic 10.3.6) and I was suggested to follow this sample web.xml for my web app project

I have followed this web.xml but I am not sure what the contextAttribute with value (shown below) in this piece does ..

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

When I am running my webapp and hitting it with REST client, I keep getting http 404 not found error. The complete error is posted here http://paste.ubuntu.com/13966788/

Here's the error snippet

    08:44:34.368 [main] DEBUG o.s.web.client.RestTemplate - GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/customers/2" resulted in 404 (Not Found); inv
    oking error handlerTests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.402 sec <<< FAILURE! - in demo.DemoApplicationTests
contextLoaded(demo.DemoApplicationTests)  Time elapsed: 0.042 sec  <<< ERROR!
org.springframework.web.client.HttpClientErrorException: 404 Not Found
        at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
        at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
        at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:289)
        at demo.DemoApplicationTests.contextLoaded(DemoApplicationTests.java:45)

i am not sure what should be my context root, The deployed webapp in the weblogic console shows the value 'demo-0.0.1-SNAPSHOT'

and my REST controller's method's @RequestMapping is /customers/{id}.

@RestController
public class CustomerRestController {
    @Autowired
    private CustomerRepository customerRepository;
@RequestMapping("/customers/{id}")
CustomerProtos.Customer customer(@PathVariable Integer id) {
    return this.customerRepository.findById(id);
}

So I assume my url path should look like

localhost:7001/demo-0.0.1-SNAPSHOT/customers/2 

but when I hit this URL (both in browser and in spring based test client) I keep getting http 404 not found error.

Here's my spring test client..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class DemoApplicationTests {

@Configuration
public static class RestClientConfiguration {

    @Bean
    RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
        return new RestTemplate(Arrays.asList(hmc));
    }

    @Bean
    ProtobufHttpMessageConverter protobufHttpMessageConverter() {
        return new ProtobufHttpMessageConverter();
    }
}
@Autowired
private RestTemplate restTemplate;
@Test
public void contextLoaded() {

    ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
            "http://localhost:7001/demo-0.0.1-SNAPSHOT/customers/2", CustomerProtos.Customer.class);

    System.out.println("customer retrieved: " + customer.toString());
}

I wonder if the contextAttribute is doing something here. Any ideas ?

The only other thing i am doing different here is instead of httpMessageConverter, I am registering Spring MVC4's ProtoBufHttpMessageConverter. But shouldn't be making a difference in this case.

My code is shared (on github) here https://github.com/robinbajaj123/spring-and-google-protocol-buffers


Solution

  • Do you have servletMapping defined as in the web.xml?

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    Also, have public for your method

    @RequestMapping("/customers/{id}")
    public CustomerProtos.Customer customer(@PathVariable Integer id) 
    

    Do you see the request mapping path being registered in the log?