In order to debug the SpringMVC code in the Spring source project, using Tomcat plug-in is more convenient, then you need to simulate the function of SpringBoot like yourself: start the Spring application, embedded Tomcat and do a good job of correlation.
Why is it so troublesome??? Because I am a common Java project, the basic web.xml file, I need to write code to add Context\Servlet to Tomcat and bind with Spring web context.
To fully understand this part of the code, you need to have a deeper understanding of Tomcat and Spring. You can take a look at the previous Spring and Tomcat source code analysis
First, create a new normal Java project in the Spring project. Note that it is built with Gradle
Other steps are omitted and only build.gradle file is pasted
plugins { id 'java' } group 'org.springframework' version '5.2.0.BUILD-SNAPSHOT' sourceCompatibility = 1.8 dependencies { compile project(":spring-context") compile project(":spring-webmvc") testCompile group: 'junit', name: 'junit', version: '4.12' compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.5.49' compile group: 'org.projectlombok', name: 'lombok', version: '1.18.10' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8' }
Why to import jackson's stuff, because I want to convert the object returned by the Controller to json string output
Upper Code:
Simulate spring boot with Tomcat container
@Configuration @ComponentScan("com.jv.webmvc") public class WebMvcMain{ public static void main(String[] args) { try { //Instantiate a Spring web context AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ac.register(WebMvcMain.class); ac.refresh(); //Instantiating Spring's DispatcherServlet DispatcherServlet and context binding DispatcherServlet dispatcherServlet = new DispatcherServlet(ac); //Instantiate Tomcat Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); //Tomcat add Servlet Context context = tomcat.addContext("/", "f:\\data\\spring-tomcat\\app"); Tomcat.addServlet(context, "st", dispatcherServlet); context.addServletMapping("/", "st"); //Start Tomcat tomcat.start(); tomcat.getServer().await(); }catch (Exception e){ e.printStackTrace(); } } }
The following class is to complete the HTTPMessageConverter registration (some friends may ask why not rewrite its methods with the WebMvcConfigure interface to complete the custom Converter addition...)... I guess it's because I can't use @ EnableWebMvc)
@Component public class MyHttpMessageConverterProcessor implements BeanPostProcessor{ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter")){ List<HttpMessageConverter<?>> messageConverters = ((RequestMappingHandlerAdapter) bean).getMessageConverters(); messageConverters.add(new MappingJackson2HttpMessageConverter()); } return bean; } }
User object
@Setter @Getter @ToString public class User { public User(){} public User(String userName,Integer age){ this.userName = userName; this.age = age; } private String userName; private Integer age; }
UserController
@RestController public class UserController { private User user = new User("Messi",33); @RequestMapping("/user") public User queryAllUser(){ System.out.println(user); return user; } }
Note that all other classes to be scanned must be in the com.jv.webmvc directory and its subdirectories
Complete the above code and start the spring MVC application
Tomcat started successfully
Browser access: http://localhost:8080/user