2

I am trying to pass a List of objects from my controller which I have to display in my jsp. However I am getting the exception,

[org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (http-localhost/127.0.0.1:8080-1) Handler execution resulted in exception: Could not find acceptable representation

The problem is that the headers are not getting set correctly inside the controller even when using produces = "application/json"

inside @RequestMapping(value = "/getEmpDetails.html", method = RequestMethod.GET, produces = "application/json" )

Perhaps this could be due to the exception Handler execution resulted in exception: Could not find acceptable representation

And in browser it is showing 406 error

JBWEB000126: The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request 'Accept' headers.

I am not able to find an answer for this,

I have checked similar posts but the answers stated there are not helping me solve my problem.

I have used jars

1) jackson-mapper-asl-1.9.13.jar

2) jackson-core-asl-1.9.13.jar

3) jackson-databind-2.8.7.jar

4) jackson-core-2.8.7.jar

5) jackson-annotations-2.8.7.jar

6) jackson-datatype-joda-2.8.7.jar

7) jackson-jaxrs-json-provider-2.8.7.jar

8) jackson-module-jaxb-annotations-2.8.7.jar

I assume that only the first one is needed.

I am not using maven structure, so there is no pom.xml. I have not made any other changes to AppConfig or WebInitializer (i am using java configuration instead of xml)

The following is my AppConfig

 @Configuration
 @EnableWebMvc
 @ComponentScan(basePackages = "com.myapps.empregister")
 public class AppConfig extends WebMvcConfigurerAdapter {


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

@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
    ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
    resolver.setContentNegotiationManager(manager);

    // Define all possible view resolvers
    List<ViewResolver> resolvers = new ArrayList<ViewResolver>();

    resolvers.add(jsonViewResolver());
    resolvers.add(defaultViewResolver());
    resolvers.add(excelViewResolver());

    resolver.setViewResolvers(resolvers);
    return resolver;
}

@Bean
public ViewResolver defaultViewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/WEB-INF/views/");
    viewResolver.setSuffix(".jsp");
    viewResolver.setOrder(2);

    return viewResolver;
}

@Bean(name="excelView")
public ViewResolver excelViewResolver() {
    ResourceBundleViewResolver viewResolver = new ResourceBundleViewResolver();
    viewResolver.setBasename("views");
    viewResolver.setOrder(1);

    return viewResolver;
}

@Bean
public ViewResolver jsonViewResolver() {
    return new JsonViewResolver();
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

@Bean(name = "multipartResolver")
public StandardServletMultipartResolver resolver() {
    return new StandardServletMultipartResolver();
}
}

WebAppInitializer/ (web.xml equivalent)

  public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] { AppConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return null;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "*.html", "*.json"};
}

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
  registration.setMultipartConfig(getMultipartConfigElement());
}

  private MultipartConfigElement getMultipartConfigElement() {
      MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
  return multipartConfigElement;
}


@Override
protected Filter[] getServletFilters() {

    CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
    encodingFilter.setEncoding("UTF-8");
    encodingFilter.setForceEncoding(true);
    ---------
}

@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
    super.registerDispatcherServlet(servletContext);

    servletContext.addListener(new HttpSessionEventPublisher());
    servletContext.addListener(new RequestContextListener());

    SessionCookieConfig cookieConfig = servletContext.getSessionCookieConfig();
    cookieConfig.setHttpOnly(true);


/*** Login Success ***/
servletContext.setInitParameter("HOME_URL", "Home.html");
servletContext.setInitParameter("SSO_ENABLED", "Yes");
servletContext.setInitParameter("SSO_LOGIN_URL", "ssoLogin.html");

/*** Login Failure ***/
servletContext.setInitParameter("LOGIN_ERROR_URL", "index.jsp");
servletContext.setInitParameter("LOGOUT_URL", "index.jsp");

/*** Bypass Redirect ***/
servletContext.setInitParameter("BYPASS-URLS", "Home.html");

servletContext.setInitParameter("defaultHtmlEscape", "true");
servletContext.setInitParameter("log4jExposeWebAppRoot", "false");  

/*** Login Page ***/
servletContext.setInitParameter("LOGIN_URL", "index.jsp");

/*** Default Home Page ***/
servletContext.setInitParameter("SHOW_DEFAULT_HOMEPAGE", "Yes");    

}


 @SuppressWarnings("unused")
 private AnnotationConfigWebApplicationContext getContext() {
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    context.setConfigLocations("com.....config");
    return context;
 }

 private static final String LOCATION = "C:/TESTdevelopments/files/"; // Temporary location where files will be stored

private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
                                            // Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.

private static final int FILE_SIZE_THRESHOLD = 0; // Size threshold after which files will be written to disk

}

JsonViewResolver class

public class JsonViewResolver implements ViewResolver{

    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setPrettyPrint(true);    
        return view;
      }

}

The following is my controller code.

@RequestMapping(method = RequestMethod.GET, value = "/getEmpDetails.html", produces="application/json;charset=utf-8")
public @ResponseBody List<EmpRecordParams> getEmpDetails(@RequestParam String id, HttpServletRequest request, HttpServletResponse response,
        Model model) {
    System.out.println("get");
    List<EmpRecordParams> empRecordParams = empRegisterService.getEmpDetails(id);
    return empRecordParams;
}

In my jsp I use ajax as follows:

var empDetails = function() {
    $
            .ajax({
                type : "GET",
                url : "${pageContext.request.contextPath}/new/getEmpDetails.html",
                headers: {Accept: '*/*'},
                data : {
                    "id" : $("#empNo").val()
                },
                success : function(data) {
                        //Other functions
                        -------------
                    }

                 }

please help me with resolving this exception.

Thanks in advance

eccentricCoder
  • 846
  • 1
  • 14
  • 35
  • 1
    Reading https://stackoverflow.com/questions/4069903/spring-mvc-not-returning-json-content-error-406?rq=1, I think you need to setup json in your `configureContentNegotiation` –  Aug 03 '17 at 10:25
  • @RC i have made changes as suggested by you, but the same exceptions is still coming up. – eccentricCoder Aug 03 '17 at 10:35
  • 1
    there's a good chance that's because the url ends with `.html` try to use `@RequestMapping(value = "/getEmpDetails.json` –  Aug 03 '17 at 11:32
  • how do you call your endpoint from the client? – P.J.Meisch Aug 03 '17 at 11:56
  • @P.J.Meisch I have updated my question mentioning the same – eccentricCoder Aug 03 '17 at 12:11
  • @RC. I have already tried that and the control doesnt even go to the controller – eccentricCoder Aug 03 '17 at 12:11
  • 1
    can you call the URL to which `${pageContext.request.contextPath}/new/getEmpDetails.html` resolves from a browser or by using curl? And does it resolve to the correct url? – P.J.Meisch Aug 03 '17 at 12:20
  • @P.J.Meisch I can see that inside my firebug itself, it is pointing to correct url. The problem is it cant resolve the returned format – eccentricCoder Aug 03 '17 at 12:28
  • @P.J.Meisch Just found out that the headers are not setting correctly inside Controller, thanks to your comment on checking the path, I found this when i rechecked to confirm the same. I have now updated my question quoting that too... – eccentricCoder Aug 03 '17 at 12:50
  • @RC. I have done everything as suggested. I have added all the dependencies, I have already added content negotiation and everything, I have searched everywhere still I am not able to find a solution, giving /getEmpDetails.json keep receiving request not found error. please help. – eccentricCoder Aug 06 '17 at 07:09
  • 1
    "keep receiving request not found error" have you chnaged you JS code to GET the json url? If you can share a full project reproducing your issue someone **might** take the time to help you (otherwise this is a dead end IMHO) –  Aug 06 '17 at 10:19
  • @RC Your suggestions helped me find the solution. Thanks a lot.. I was completely lost in this for the past few days. Wouldnt have found a solution if not for your suggestions. – eccentricCoder Aug 06 '17 at 10:44

1 Answers1

2

Finally I found an answer to this,

The change was not much, but took a lot of time to notice the same.

I made the following changes to

WebAppInitializer.java (which is the equivalent for web.xml)

@Override
protected String[] getServletMappings() {
return new String[] { "*.html", "*.json" };
}

It was so simple, I regret myself for not finding this before.

then I changed .ignoreAcceptHeader(false) in configureContentNegotiation in

AppConfig.java

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

Finally I made changes in both ajax call and Controller @RequestMapping to call getEmpDetails.json

And so it was solved.

The most important part was the servlet mapping without that it wouldnt have been possible.

Thanks especially to @RC and @ P.J.Meisch for helping me solve this. and thanks to everyone who took time to look into this.

eccentricCoder
  • 846
  • 1
  • 14
  • 35