Struts2学习笔记一之Struts2入门

     大家都知道Struts2是一个MVC框架,我们javaWeb中学习的servlet也是一个mvc框架,那我要问大家一个问题,为什么要用struts2开发呢?怎么不使用serlet来开发呢?

那我们先来讨论一下servlet的缺点,它的缺点有哪些呢?


1. Servlet回顾

 

 

1.1. 第一步:创建一个Servlet类,继承HttpServlet

1.2. 第二步:编写doGet方法,传递requestresponse参数

1.3. 第三步:转向index.jsp页面

 

package com.dn.servlet;

 

import java.io.IOException;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class HelloServlet extends HttpServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{

String method = (String)request.getParameter("method");

if("hello".equals(method)){

System.out.println("hello world.");

}else if("hey".equals(method)){

System.out.println("hey world.");

}

request.getRequestDispatcher("/index.jsp").forward(request, response);

}

}

1.1. 第四步:在web.xml中配置servlet

 

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>springmvc</display-name>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

  

<servlet>

<servlet-name>helloServlet</servlet-name>

<servlet-class>com.dn.servlet.HelloServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>helloServlet</servlet-name>

<url-pattern>/servlet/helloServlet</url-pattern>

</servlet-mapping>

  

</web-app>

 

1.2. 第五步:发布,测试

2. Servlet的缺点

1)写一个Servlet要在web.xml中配置8行代码,当项目中有很多servlet会导致web.xml比较庞大,杂乱,不易维护

2)在项目中多人编辑同一个web.xml,容易导致版本冲突问题

3)在servlet中,一个方法的入口只有一个,如果在servlet中写很多方法,这些方法应该传递参数,根据每次请求的参数不同来判断具体执行哪个方法。

4)如果在表单中的元素很多,在servlet中要想获取表单中的数据,那么在servlet的方法中必要有大量的request.getParameter()方法。码农的最佳实践,和业务逻辑毫无关系。字符串还简单,强转;对应int,float,data还需要写额外的null判断。

5Servlet中有两个参数requestresponse,这两个参数有严重容器依赖性。所以在servlet中写的代码不能单独测试的。

6)如果在servlet中的一个方法中,有很多功能,这个时候会导致该方法比较复杂,以至于不利于维护

doGet(){

权限的验证

用户注册

用户头像图片上传

验证表单

方法的执行效率

}

 

7)在servlet中声明成员变量,会存在线程安全问题。

 

重构:

1)更有利于团队开发,提高开发效率

2)克服上面这些缺点。其实对照上面的问题,你看看struts2怎么解决,也就会使用struts2了。

 

servlet说的一无是处,那它有优点吗?

1Servlet能让你看到mvc框架的本质,它是不最底层的东西啊。实际struts2就是对它的封装。

2)越底层的东西执行效率越高。也就是现在欧美很多企业仍然直接使用servlet,因为什么啊,它的掌控性比较强,自己可以一层层的重构,所有东西都是你自己写的,那看起来会怎样?是不容易读懂啊。那你要使用struts2,是不还得研究它的源代码啊。Struts2高度封装,可不是那么容易研究。

 

struts2怎么样对servlet重构呢?下节来说。

3. Servlet的重构

怎么做这个事呢?

 

需求:

用户IE输入URL,解析URL找到具体的业务执行,然后转向页面展现结果。

 

有什么?(资源)

URLaction的名字;

Actionexecute方法,转向的页面名称

Jsp页面

 

缺什么?(如何整合资源实现需求)

当前有哪些action (通过监听器进行初始化对应关系)

url怎么定位action?  (过滤器实现,struts2就用过滤器实现)

Action的方法怎么执行? (通过反射)

怎么完成转向? (request的转向方法)

 

1)监听器

  a)准备一个map

  b)把所有的action都以key,value的形式放到map

  c)map放到application

2)过滤器

  a)application中获取map

  b)解析url

  c)根据解析的urlmap中获取value

  d)根据java的反射机制动态调用action中的值

  e)根据action返回的字符串进行跳转

3)执行actionexecute的方法,返回字符串


1. Servlet重构的实现

1.1. 第一步:创建web工程 superservlet

1.1. 第二步:创建监听器

配置URL对应的实现类

 

package com.dn.listener;

 

import java.util.HashMap;

import java.util.Map;

 

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

 

public class ServletListener implements ServletContextListener {

 

//摧毁,释放资源

public void contextDestroyed(ServletContextEvent arg0) {

arg0.getServletContext().removeAttribute("mappings");

}

 

//tomcat容器启动时,进行初始化

public void contextInitialized(ServletContextEvent arg0) {

Map<String,Object> map = new HashMap<String,Object>();

map.put("loginAction", "com.dn.action.LoginAction");

//mapping放入application

arg0.getServletContext().setAttribute("mappings", map);

}

 

}


1.1. 第三步:创建filter

 

package com.dn.filter;

 

import java.io.IOException;

import java.lang.reflect.Method;

import java.util.Map;

import java.util.Map.Entry;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import com.dn.utils.ServletUtils;

 

public class DispatcherFilter implements Filter{

//摧毁

public void destroy() {

}

 

//执行体,处理业务逻辑

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

try {

//获取用户的请求

HttpServletRequest req = (HttpServletRequest) request; //重载,HttpServletRequestServletRequest的子接口

String actionName = ServletUtils.getActionName(req.getRequestURI());

ServletContext sc = request.getServletContext(); //获取上下文

//从上下文中拿出map

Map<String,Object> mappings = (Map)sc.getAttribute("mappings");

for(Entry entry : mappings.entrySet()){

if("loginAction".equals(entry.getKey())){

//利用反射得到执行的actionmethod

Class clazz = Class.forName((String)entry.getValue());

Method method = clazz.getMethod("execute", HttpServletRequest.class, HttpServletResponse.class);

//执行指定的action的指定方法,并获取返回值

String jspName = (String)method.invoke(clazz.newInstance(), request, response);

//根据action的返回值跳转

request.getRequestDispatcher(jspName).forward(request, response);

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

 

//初始化

public void init(FilterConfig arg0) throws ServletException {

}

 

}

 

 

1.1. 第四步:工具类,解析action名称

package com.dn.utils;

 

/**

 * @Description:

 * @Author: 达内集团  教学研发部    大数据方向 陈子枢

 * @Company: http://www.tarena.com.cn

 * @CreateDate: 201539

 */

public class ServletUtils {

static public String getActionName(String url){

url.split("/"); // /loginAction.action

String[] array = url.split("/");

String _str = array[array.length-1];

return _str.substring(0, _str.indexOf("."));

}

}

 

1.2. 第五步:创建userAction

package com.dn.action;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

/**

 * @Description:

 * @Author: 达内集团  教学研发部    大数据方向 陈子枢

 * @Company: http://www.tarena.com.cn

 * @CreateDate: 201539

 */

public class LoginAction {

public String execute(HttpServletRequest request, HttpServletResponse response){

System.out.println("login action execute");

return "index.jsp"; //转向index.jsp页面

}

}

 

 

 

1.3. 第六步:web.xml配置filter

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>springmvc</display-name>

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

  

   <listener>

   <listener-class>com.dn.listener.ServletListener</listener-class>

   </listener>

  

<filter>

<filter-name>DispatcherFilter</filter-name>

<filter-class>com.dn.filter.DispatcherFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>DispatcherFilter</filter-name>

<url-pattern>*.action</url-pattern>

</filter-mapping>

  

</web-app>

 

 

小结

Action中是不跟原来servlet一样,它不就要request,response吗,都有。

 

这样比起来

web.xml中就一个声明,再有新的action,只需在监听器中配置即可

Action方法动态调用

这就是重构,是不是比原来方便很多,代码结果非常清晰。

 

 

当然这里有很多不足

ServletListener中是不要有新的servlet还得再这写;

是不如果进一步的优化,还可以把它写入配置文件中啊,那样是不就更完美了。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值