java web编写通用servlet、编码器

目录

通用servlet

测试页面

BaseServlet

对应的servlet里

通用编码器


前言

如果使用最基本的servlet进行项目编写,那么每个请求都需要写一个servlet,这样数量过于庞大

所以需要一个通用servlet,通过反射和代理,将请求归类,比如学生请求,就只有一个学生的servlet

servlet里面有很多方法,具体看代码

通用servlet

测试页面

username和passwor是用于测试通用servlet接受参数的情况,并不对数据库进行操作

BaseServlet

BaseServlet的作用就是获取从前台传过来的方法名称,然后利用反射调用对应的方法

1 StudentServlet继承BaseServlet,这样当我们请求 studentServlet?method=login  的时候

会默认调用父类BaseServlet无参的构造方法,BaseServlet也会调用父类HttpServlet的无参构造方法

2 HttpServlet的无参构造方法里默认调用init方法,init里面默认调用service方法,这时候service被重写

所以调用BaseServlet里的service方法

3 最后利用反射调用对应的方法

public class BaseServlet extends HttpServlet
{
	// 重写service,因为当请求过来的时候,会自动调用service,所以在这里做文章
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		try
		{
			// 获取method参数的数值
			String md = request.getParameter("method");

			// 存放要转发的路径,因为执行完方法后可能需要跳转页面
			String path = null;

			// 获取当前调用对象的字节码对象,也就是子类的对象
			Class clazz = this.getClass();
			
			//获取子类对象的Method,md是方法的名称,后面2个是参数类型
			Method method=clazz.getMethod(md,HttpServletRequest.class,HttpServletResponse.class);
			
			//如果获取到了
			if (null!=method)
			{
				//调用这个方法,并且传递参数下去,所以我们的方法也需要写上 request,response这2个参数
				//this是承载的对象,如果要调用的方法是静态的,那么不需要对象承载
				//现在这个this,并不是子类对象,而是父类对象,相当于是父类调用子类的方法,因为是用父类来承载的
				//上面的 this.getClass(); 返回的是当前调用对象的字节码对象,为什么这样,需要解析getClass源码
				//method.invoke的返回值是Object,也就是我们在studentServlet里的方法可以是任意类型
				//而我们强制限制它是String,这里返回的数值也就是我们方法返回的数值
				path=(String) method.invoke(this, request,response);
			}
			
			//如果path也不为空,注意上面已经用了方法了
			if (null!=path)
			{
				//这里用于转发我们方法返回的地址,由BaseServlet帮我们转发,我们只需要在返回值上写要转发的路径即可
				request.getRequestDispatcher(path).forward(request, response);
			}

		} catch (Exception e)
		{
			e.printStackTrace();
		}

	}
}

对应的servlet里

public class StudentServlet extends BaseServlet
{
	//返回值必须是String
	public String login(HttpServletRequest request,HttpServletResponse response)
	{
		String username=request.getParameter("username");
		System.out.println(username);
		
		//这里写你需要去的页面即可,记得一定要加/
		return "/index.html";
	}
}

通用编码器

只要理解核心部分即可,一个是如果是post请求,直接reques.setChracterEncoding("utf-8")

如果是get请求,把所有的参数都解码转码即可

keySet获取的是参数名,而get(key)获取就是数值的数组

	public Map<String,String[]> getParameterMap() {  
		
		/**
		 * 首先判断请求方式
		 * 若为post  request.setchar...(utf-8)
		 * 若为get 将map中的值遍历编码就可以了
		 */
		String method = request.getMethod();
		if("post".equalsIgnoreCase(method)){
			try {
				request.setCharacterEncoding("utf-8");
				return request.getParameterMap();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if("get".equalsIgnoreCase(method)){
			Map<String,String[]> map = request.getParameterMap();
			if(flag){
				for (String key:map.keySet()) {
					String[] arr = map.get(key);
					//继续遍历数组
					for(int i=0;i<arr.length;i++){
						//编码
						try {
							arr[i]=new String(arr[i].getBytes("iso-8859-1"),"utf-8");
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
					}
				}
				flag=false;
			}
			//需要遍历map 修改value的每一个数据的编码
			
			return map;
		}
		
		return super.getParameterMap();
	}

猜你喜欢

转载自blog.csdn.net/yzj17025693/article/details/88554048