同一个Servlet处理多请求,并实现不同业务逻辑
1.问题
如果仅是纯JavaWeb项目时,每个Servlet仅能处理一个请求,并且需要在web.xml配置或者使用@WebServlet,开发系统时需要配置特别多的Servlet,不利于开发。
2.解决方案
核心思想: 利用@WebServlet的value属性,配置多个请求映射到Servlet,截取请求路径(如:requestUrl.json截取为requestUrl),将requestUrl作为Servelt中的方法名,利用发射找到requestUrl方法并执行
2.1 @WebServlet
@WebServlet中的value属性是数组,并用此来匹配请求地址
package javax.servlet.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
可以在注解Servlet类时根据需要配置多个请求地址
@WebServlet(
{
"/pbom/addProfessionalRoad.do",
"/pbom/professionalRoadList.do",
"/pbom/saveProfessionalRoad.do",
"/pbom/editProfessionalRoad.do",
"/pbom/updateProfessionalRoad.do",
"/pbom/deleteProfessionalRoad.do",
"/pbom/copyRoadList.do",
"/pbom/copyRoadView.do",
"/pbom/copyPbomRoad.do",
"/pbom/findSequencesByRoadIds.do"
}
)
public class PbomRoadServlet extends HttpServlet
{
}
2.2 利用反射执行请求地址对应方法
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//获取请求的URI地址
String url = request.getRequestURI();
//后缀名
String suffix = url.substring(url.lastIndexOf(".") + 1, url.length());
//截取方法名
String methodName = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
Method method = null;
try
{
method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//执行方法
method.invoke(this, request, response);
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
3. 【进阶实现】抽取反射操作到父类方法中,子类直接继承
基类:BaseServlet
package com.northeo.dynamic.data.servlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet
{
private static final Logger logger = LoggerFactory.getLogger(SysDynamicDataSourceServlet.class);
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
{
//获取请求的URI地址
String url = request.getRequestURI();
//后缀名
String suffix = url.substring(url.lastIndexOf(".") + 1, url.length());
//截取方法名
String methodName = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
Method method = null;
try
{
method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.setAccessible(true);
//执行方法
method.invoke(this, request, response);
} catch (NoSuchMethodException e)
{
logger.error("Servlet方法: {} 未找到!", methodName, e);
} catch (IllegalAccessException e)
{
logger.error("反射无权限!", e);
} catch (InvocationTargetException e)
{
logger.error("Servlet方法: {} 执行出错!", methodName, e);
}
}
protected void responseMessage(HttpServletResponse response, Object msg)
{
try
{
response.getWriter().print(msg);
} catch (IOException e)
{
logger.error("IO错误!", e);
}
}
}
实现类:CommonInfoServlet
package com.northeo.dynamic.data.servlet;
import com.northeo.dynamic.data.service.CommonInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@WebServlet(
{
"/dynamic-data/common/getJdbcUrl.json"
}
)
public class CommonInfoServlet extends BaseServlet
{
private static final Logger logger = LoggerFactory.getLogger(CommonInfoServlet.class);
private CommonInfoService service = new CommonInfoService();
private void getJdbcUrl(HttpServletRequest request, HttpServletResponse response)
{
System.out.println(response.getContentType());
System.out.println(response.getCharacterEncoding());
System.out.println(response);
}
}