ENV
spring boot 2.6.0
UnitTest
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
@RunWith(SpringJUnit4ClassRunner.class) // @RunWith: integrate spring with junit
@SpringBootTest(classes = {PemoApplication.class}) // @SpringBootTest: this class is spring boot test.
public class UserServiceTest {
@Resource
private UserService userService;
@Test
public void testGetUser() {
Assert.assertEquals(userService.getUser(), "Tom");
}
}
Logging
Spring boot logback
application.properties
debug=true
logging.level.root=DEBUG
logging.file.path=/var/log
logging.file.name=myspringboot.log
@RestController
public class LoggingController {
Logger logger = LoggerFactory.getLogger(LoggingController.class);
@RequestMapping("/log")
public Map<String, Object> hellolog() {
Map<String, Object> result = new HashMap<>();
result.put("name", "Stephen");
logger.info("this is a info message");
logger.warn("this is a warn message");
logger.error("this is an error message");
return result;
}
}
Validation
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Hotswap
- maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
Then you can run project using ./mvnw spring-boot:run
. And when you modify thymeleaf templates or other classes of the project, the modified part will be reloaded automatically.
- IEDA
If you want to run the project in IDEA, you should make the checkbox checked for IDEA 2021.2.
Settings
-> Advanced Settings
-> Allow auto-make to start even if developed application is currently running
thymeleaf
application.properties
spring.thymeleaf.enabled=true
spring.thymeleaf.check-template-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.suffix=.html
Exception
Method 1
@ControllerAdvice
and @ExceptionHandler
@ControllerAdvice //to write global code that can be applied to a wide range of controllers
public class GlobalExceptionHandler {
@ExceptionHandler(value = {java.lang.ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception e) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exceptionmsg", "ArithmeticException from GlobalExceptionHandler with ControllerAdvice");
modelAndView.setViewName("exceptions");
return modelAndView;
}
@ExceptionHandler(value = {java.lang.NullPointerException.class})
public ModelAndView handleNullPointerException(Exception e) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exceptionmsg", "NullPointerException from GlobalExceptionHandler with ControllerAdvice");
modelAndView.setViewName("exceptions");
return modelAndView;
}
}
Method 2
@Configuration
, @Bean
and SimpleMappingExceptionResolver
@Configuration
public class MySimpleMappingExceptionResolver {
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties propertiesMap = new Properties();
// Exception name and View name
propertiesMap.put("java.lang.ArithmeticException", "exceptionsresolver");
propertiesMap.put("java.lang.NullPointerException", "exceptionsresolver"); // Is it a bug for multi-exceptions program with only one view? The view name can be various for different exceptions.
simpleMappingExceptionResolver.setExceptionMappings(propertiesMap);
// default attribute name is "exception"
return simpleMappingExceptionResolver;
}
}
Method 3
@Configuration
and HandlerExceptionResolver
@Configuration
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, @Nullable Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof ArithmeticException) {
modelAndView.setViewName("exceptionsresolver");
}
if (e instanceof NullPointerException) {
modelAndView.setViewName("exceptionsresolver");
}
modelAndView.addObject("exception", e.toString() + " from HandlerExceptionResolver");
return modelAndView;
}
}
priority
Method 1 > Method 2 > Method 3