eccentricCoder
eccentricCoder

Reputation: 844

406 Error when trying to parse json returned from Spring-MVC Controller

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

Upvotes: 2

Views: 815

Answers (1)

eccentricCoder
eccentricCoder

Reputation: 844

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.

Upvotes: 2

Related Questions