新型的用户登陆注册
我们会发现,无论什么Servlet上最终还是跳转到相对应的JSP页面的...也就是说,第一和第二步骤【封装数据、调用Service】我们可以封装起来…只要返回uri给Servlet跳转到JSP页面就好了。
LoginAction
返回的uri分两种情况:
- 如果是转发,那么返回的是RequestDispatcher对象
- 如果是重定向,那么返回的是字符串
/** * Created by ozc on 2017/4/26. * <p> * 一个Action对应一个Servlet,Action负责处理具体的请求 */ public class LoginAction { public Object login(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { Object uri ; //得到用户带过来的数据,封装到Bean对象中 String username = request.getParameter("username"); String psd = request.getParameter("psd"); User user = new User(); user.setPsd(psd); user.setUsername(username); try { //调用Service方法 UserService userService = new UserService(); userService.longin(user); //登陆成功跳转到首页 request.getSession().setAttribute("user", user); //跳转到首页的时候需要重定向 //response.sendRedirect(request.getContextPath() + "/index.jsp"); //如果是重定向,那么返回的是字符串 uri = "/index.jsp"; return uri; } catch (Exception e) { e.printStackTrace(); //登陆失败,跳转到相关的提示页面 request.setAttribute("message","登陆失败了!!!"); //request.getRequestDispatcher("/message.jsp").forward(request, response); //如果是转发,那么返回的是RequestDispatcher对象 uri = request.getRequestDispatcher("/message.jsp"); return uri; } } }
LoginServlet就可以写成这样了:
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { //得到LoginAction对象 LoginAction loginAction = new LoginAction(); Object uri = loginAction.login(request, response); //是重定向 if (uri instanceof String) { response.sendRedirect(request.getContextPath() + uri); } else { //是转发,强转成是RequestDispatcher对象 ((RequestDispatcher) uri).forward(request, response); } }
RegisterAction
RegisterAction
/** * Created by ozc on 2017/4/26. * * 一个Action对应一个Servlet,Action负责处理具体的请求 */ public class RegisterAction { public Object register(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { Object uri ; //得到用户带过来的数据,封装到Bean对象中 String username = request.getParameter("username"); String psd = request.getParameter("psd"); User user = new User(); user.setPsd(psd); user.setUsername(username); try { //调用Service方法 UserService userService = new UserService(); userService.register(user); //登陆成功跳转到登陆页面 uri = request.getRequestDispatcher("/login.jsp"); return uri; } catch (Exception e) { e.printStackTrace(); //注册失败,跳转到相关的提示页面 request.setAttribute("message","注册失败了!!!"); //request.getRequestDispatcher("/message.jsp").forward(request, response); uri = request.getRequestDispatcher("/message.jsp"); return uri; } } }
RegisterServlet
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { //得到RegisterAction RegisterAction registerAction = new RegisterAction(); Object uri = registerAction.register(request, response); //是重定向 if (uri instanceof String) { response.sendRedirect(request.getContextPath() + uri); } else { //是转发,强转成是RequestDispatcher对象 ((RequestDispatcher) uri).forward(request, response); } }
思考
到目前为止,我们搞了两个Action类来封装Servlet的逻辑代码,我们再次看回Servlet的代码。
可以很清楚地发现:两个实现不同功能的Servlet仅仅是调用的Action不同….如果是仅仅调用的Action不同【通过反射来调用不同的Action】,那么我们应该想到使用一个Servlet来管理整个项目,也就是说:整个web项目只有一个核心的控制器
问题:
①:我们在之前是直接指明Servlet的映射路径了,现在要ActionServlet处理所有的请求,我们只要定一个规则:只要后缀为.action的,那么都交由核心控制器ActionServlet来控制….
②:现在全部的请求已经交由ActionServlet控制,那怎么知道调用的是哪个Action???我们可以通过请求的uri,比如:http://localhost:8080/login.action
,其中login就代表的是调用LoginAction..也就是说login=LoginAction,我们可以通过properties文件来配置..
③:现在我们已经知道了调用的是哪个Action了,但是Action可能不仅仅只有一个方法,我们还要在调用的时候,指定的方法名是什么.这很简单,一般我们都是职责分工明确的,method=login….并且,调用的Action和具体的方法也是有关系的,不可能是孤立存在的。因此,我们的配置文件是不能使用properties的,需要使用XML
④:在调用方法的时候,是返回一个Object的uri的,uri的类型可能是String、也可以能是RequestDispatcher、并且返回的结果可能有几种情况的【可能跳转到首页,也可能跳转到登陆界面】
⑤:Action调用的方法和返回的uri也是是有关系的!…..不同的Action调用不同的方法,返回的uri也是不同的….
⑥:要跳转到哪个页面上,可以通过标识量来识别….比如:success表示成功执行,如果要重定向那么多加个type类型,如果不重定向就没有type类型..路径使用path来表示..因此,在具体的Action中,就不需要返回具体的uri,只要返回一个标识量即可
画一张图来梳理一下思路:
XML配置
我们可以写出这样的XML配置,当ActionServlet初始化的时候,读取XML配置文件,就知道调用的是什么Action,Action中的什么方法,以及跳转到哪个页面上了。
<?xml version="1.0" encoding="UTF-8" ?> <mystruts> <package> <action name="login" className="zhongfucheng.servlet.LoginServlet" method="login"> <!--是否存在type属性,存在则是重定向,不存在则是转发--> <!--result的值表示的就是跳转的路径--> <result name="success" type="redirect">/index.jsp</result> <result name="fail">/message.jsp</result> </action> <action name="register" className="zhongfucheng.servlet.RegisterServlet" method="register"> <!--是否存在type属性,存在则是重定向,不存在则是转发--> <!--result的值表示的就是跳转的路径--> <result name="success">/message.jsp</result> <result name="fail">/message.jsp</result> </action> </package> </mystruts>
为了更好地管理这些信息,我们应该使用JavaBean来对它们封装
- ActionMappingManager-------管理全部的Action
/** * Created by ozc on 2017/4/26. * * 该类管理着全部的Action * * 要管理全部的Action,就需要用一个容器来装载这些Action * * 选择Map集合是最合适的,可以通过key来得到Action,key就是<action name=><action/>中的name属性 * */ public class ActionMappingManager { private Map<String, ActionMapping> map = new HashMap<>(); //注意:外界都是通过name来得到对应的Action的,并不会获取得到整个Manager public ActionMapping getActionMapping(String name) { return map.get(name); } }
ActionMapping----表示单个的Action
public class ActionMapping { //所有的results private Map<String, Results> results; //关键字name private String name; //要调用的Action路径 private String className; //Action中的方法 private String method; public Map<String, Results> getResults() { return results; } public void setResults(Map<String, Results> results) { this.results = results; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }
Results---表示的是结果视图
/** * Created by ozc on 2017/4/26. * * 该类表示的是结果视图 * * * */ public class Results { //方法返回的标识 private String name; //要跳转的方式 private String type; //要跳转的页面 private String page; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getPage() { return page; } public void setPage(String page) { this.page = page; } }