有些老项目还在使用原始的Http Servlet或是struts2, 而新功能都期望使用spring, 而spring已经不使用web.xml配置了. 折中的解决方法:
整合struts2
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Bean
public FilterRegistrationBean registration() {
//web.xml中的struts filter移到代码中
StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter();
FilterRegistrationBean<StrutsPrepareAndExecuteFilter> registration =
new FilterRegistrationBean<>(filter);
registration.addUrlPatterns("/test/*");
registration.addInitParameter("config", "struts-default.xml,struts2/struts-test.xml");
return registration;
}
}
兼容原始的Servlet
public class MyServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("hello servlet1");
}
}
public class MyServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("hello servlet2");
}
}
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Bean
public ServletRegistrationBean<HttpServlet> helloServlet1() {
ServletRegistrationBean<HttpServlet> servRegBean = new ServletRegistrationBean<>();
servRegBean.setServlet(new MyServlet1());
servRegBean.addUrlMappings("/servlet1");
return servRegBean;
}
@Bean
public ServletRegistrationBean<HttpServlet> helloServlet2() {
ServletRegistrationBean<HttpServlet> servRegBean = new ServletRegistrationBean<>();
servRegBean.setServlet(new MyServlet2());
servRegBean.addUrlMappings("/servlet2");
return servRegBean;
}
}
不推荐使用@ServletComponentScan
和@WebServlet
, 因为不生效
自动批量导入web.xml中的Servlet
如果web.xml中配置的servlet太多, 手动改太累, 可以使用dom4j解析web.xml, 然后批量导入
先将web.xml移到resources目录下
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServlet;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
@Configuration
public class WebxmlCompatible implements ServletContextInitializer {
private final static Logger log = LogManager.getLogger(WebxmlCompatible.class);
private static class ServletConfig{
public String name; //servlet-name
public String clsssName;
public List<String> patterns = new LinkedList<>(); //url-pattern
public boolean loadOnStartup; //load-on-startup
public boolean asyncSupported;
public HashMap<String, String> initParams = new HashMap<>();
public MultipartConfigElement multipart = null;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try (InputStream inputStream = classLoader.getResourceAsStream("web.xml")) {
if(inputStream == null){
return;
}
log.info("web.xml: {}", classLoader.getResource("web.xml"));
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
Element root = document.getRootElement();
HashMap<String, ServletConfig> servlets = new HashMap<>();
{
List<Element> elems = root.elements("servlet-mapping");
if (elems != null) {
for (Element elem : elems) {
ServletConfig config = new ServletConfig();
String servletName = elem.element("servlet-name").getStringValue();
config.name = servletName;
servlets.put(servletName, config);
List<Element> patternElems = elem.elements("url-pattern");
for(Element pattern : patternElems){
config.patterns.add(pattern.getStringValue());
}
log.info("servletName: {}, servletPattern: {}", servletName, config.patterns);
}
}
}
{
List<Element> elems = root.elements("servlet");
if (elems != null) {
for (final Element elem : elems) {
final String servletName = elem.element("servlet-name").getStringValue();
final String servletClass = elem.element("servlet-class").getStringValue();
final ServletConfig config = servlets.get(servletName);
if(config == null){
throw new Exception("not found pattern for class: " + servletClass);
}
log.info("servletName: {}, servletClass: {}", servletName, servletClass);
config.clsssName = servletClass;
{
final List<Element> initparams = elem.elements("init-param");
if (initparams != null) {
for (Element param : initparams) {
String paramName = param.element("param-name").getStringValue();
String paramValue = param.element("param-value").getStringValue();
log.info("init paramName: {}, paramValue: {}", paramName, paramValue);
config.initParams.put(paramName, paramValue);
}
}
}
{
final Element multipartElem = elem.element("multipart-config");
if(multipartElem != null) {
Element location = multipartElem.element("location");
Element maxFileSize = multipartElem.element("max-file-size");
Element maxRequestSize = multipartElem.element("max-request-size");
Element fileSizeThreshold = multipartElem.element("file-size-threshold");
if(location != null && maxFileSize != null && maxRequestSize != null
&& fileSizeThreshold != null){
config.multipart = new MultipartConfigElement(location.getStringValue(),
Long.parseLong(maxFileSize.getStringValue()),
Long.parseLong(maxRequestSize.getStringValue()),
Integer.parseInt(fileSizeThreshold.getStringValue())
);
}
}
}
{
final Element asyncSupported = elem.element("async-supported");
if(asyncSupported != null){
String v= asyncSupported.getStringValue();
if(v.startsWith("t") || v.startsWith("T") || v.equals("1")){
config.asyncSupported = true;
}
}
}
{
final Element startup = elem.element("load-on-startup");
if(startup != null){
String v= startup.getStringValue();
if(v.startsWith("t") || v.startsWith("T") || v.equals("1")){
config.loadOnStartup = true;
}
}
}
}
}
}
for (ServletConfig servletConfig : servlets.values()) {
Class<? extends javax.servlet.http.HttpServlet> cls = (Class<HttpServlet>)
Class.forName(servletConfig.clsssName);
HttpServlet servlet = cls.newInstance();
ServletRegistration.Dynamic serviceServlet = servletContext.addServlet(servletConfig.name, servlet);
serviceServlet.addMapping(servletConfig.patterns.toArray(new String[servletConfig.patterns.size()]));
serviceServlet.setAsyncSupported(servletConfig.asyncSupported);
serviceServlet.setLoadOnStartup(servletConfig.loadOnStartup?1:0);
serviceServlet.setInitParameters(servletConfig.initParams);
if(servletConfig.multipart != null) {
serviceServlet.setMultipartConfig(servletConfig.multipart);
}
}
}catch (Exception ex){
throw new ServletException(ex);
}
}
}
兼容原有的listener
也可以通过上一节中的web.xml取出listener, 然后自动配置
@Configuration
public class WebxmlCompatible implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(new MyListener());
}
}
遇到的坑
struts2不支持servlet 3.1, 导致无法上传文件, 解决办法:
https://blog.csdn.net/wzj_whut/article/details/88219274