Tag Archives: spring

Best approach for deploying Angular app in Spring Boot

Avoid @EnableWebMvc

WebConfig

package net.pupli.web_server.config;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.GzipResourceResolver;
import org.springframework.web.servlet.resource.PathResourceResolver;

import java.io.IOException;
import java.util.List;

@Configuration
@EnableAutoConfiguration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // enable cache for static files
/*        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600 * 24 * 7);*/

        // serve pre gzip files in static folder
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600 * 24 * 7)
                .resourceChain(false)
                .addResolver(new EncodedResourceResolver());
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/notFound").setViewName("forward:/index.html");
    }

    @Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
        return container -> {
            container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                    "/notFound"));
        };
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
        converters.add(gsonHttpMessageConverter);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

References
https://stackoverflow.com/questions/44692781/configure-spring-boot-to-redirect-404-to-a-single-page-app
https://stackoverflow.com/questions/39331929/spring-catch-all-route-for-index-html/42998817

Spring Boot: Configuring a Main Class

Spring Boot 1.x

jar {
    baseName = 'interface'
    version = '0.0.1-SNAPSHOT'
    manifest {
        attributes 'Main-Class': 'net.pupli.sobhan.SobhanApplication'
    }
}

Spring Boot 2.x

springBoot {
    mainClassName = 'org.baeldung.DemoApplication'
}

or

bootJar {
    mainClassName = 'org.baeldung.DemoApplication'
}
bootJar {
    manifest {
    attributes 'Start-Class': 'org.baeldung.DemoApplication'
    }
}

References

https://www.baeldung.com/spring-boot-main-class

Configure gson in Spring using GsonHttpMessageConverter

Excluding jackson from classpath

@SpringBootApplication
@EnableAutoConfiguration(exclude = { JacksonAutoConfiguration.class })
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Using java config

@Configuration
@EnableWebMvc
public class Application extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter < ? >> converters) {
        GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
        converters.add(gsonHttpMessageConverter);
    }
}

References
https://www.leveluplunch.com/java/tutorials/023-configure-integrate-gson-spring-boot/

Spring CORS No ‘Access-Control-Allow-Origin’ header is present

Enabling CORS for the whole application is as simple as:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

To enable CORS for the whole controller:

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

To enable CORS for the method:

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

References
https://stackoverflow.com/questions/35091524/spring-cors-no-access-control-allow-origin-header-is-present

How to Use CommandLineRunner in Spring Boot Application

package com.therealdanvega;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
 
@Component
public class DataLoader implements CommandLineRunner {
 
    private final Logger logger = LoggerFactory.getLogger(DataLoader.class);
 
    @Override
    public void run(String... strings) throws Exception {
        logger.info("Loading data...");
 
    }
}

References
https://www.quickprogrammingtips.com/spring-boot/how-to-use-commandlinerunner-in-spring-boot-application.html
http://therealdanvega.com/blog/2017/04/07/spring-boot-command-line-runner

@PathVariable in Spring Boot

    @RequestMapping("/news/{year}/{month}/{day}/{title}")
    public ModelAndView news(HttpServletRequest request, HttpServletResponse response,
                             @PathVariable int year, @PathVariable int month, @PathVariable int day,
                             @PathVariable String title) {

        SessionBL sessionManager = new SessionBL(request, response);

        String postUrl = String.format("/%d/%d/%d/%s", year, month, day, title);

        ModelAndView modelAndView = new ModelAndView("index");
        modelAndView.addObject("version", new Statics().getVersion());
        return modelAndView;
    }

References
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates-regex
https://www.mkyong.com/spring-mvc/spring-rest-requestmapping-extract-incorrectly-if-value-contains/