java框架篇(二)

一、 springMVC

1.springMVC是什么?
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。

2.MVC设计模式
MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
模型:用于存储数据以及处理用户请求的业务逻辑。可以理解为领域模型、业务逻辑层、数据持久层。
视图:向控制器提交数据,显示模型中的数据。
控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有关结果交给哪个视图更新显示。

3.springMVC处理用户请求的完整流程
Spring MVC 框架主要由 DispatcherServlet、处理器映射、控制器、视图解析器、视图组成,其工作原理如图 1 所示。
在这里插入图片描述
从图 1 可总结出 Spring MVC 的工作流程如下:

Springmvc架构原理解析
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler
可以根据xml配置、注解进行查找
第三步:处理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView
ModelAndView是springmvc框架的一个底层对象,包括 Model和view
第八步:前端控制器请求视图解析器去进行视图解析
根据逻辑视图名解析成真正的视图(jsp)
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染
视图渲染将模型数据(在ModelAndView对象中)填充到request域
第十一步:前端控制器向用户响应结果

4.SpringMVC接口
Spring MVC 所有的请求都经过 DispatcherServlet 来统一分发,在 DispatcherServlet 将请求分发给 Controller 之前需要借助 Spring MVC 提供的 HandlerMapping 定位到具体的 Controller。

HandlerMapping 接口负责完成客户请求到 Controller 映射。

Controller 接口将处理用户请求,这和 Java Servlet 扮演的角色是一致的。一旦 Controller 处理完用户请求,将返回 ModelAndView 对象给 DispatcherServlet 前端控制器,ModelAndView 中包含了模型(Model)和视图(View)。

从宏观角度考虑,DispatcherServlet 是整个 Web 应用的控制器;从微观考虑,Controller 是单个 Http 请求处理过程中的控制器,而 ModelAndView 是 Http 请求过程中返回的模型(Model)和视图(View)。

ViewResolver 接口(视图解析器)在 Web 应用中负责查找 View 对象,从而将相应结果渲染给客户。

5.创建一个简单的springmvc项目
1.新建web项目
2.引入相应jar包
3.编写web.xml

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>springMVC</display-name>
    <!-- 部署 DispatcherServlet -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 表示容器再启动时立即加载servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 处理所有URL -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
<!-- 部署 DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

4.编写页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    未注册的用户,请<a href="${pageContext.request.contextPath }/register"> 注册</a><br/>
    已注册的用户,去<a href="${pageContext.request.contextPath }/login"> 登录</a></body>
</html>

5.编写Controller类

第一种方式:实现Controller接口

public class LoginController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("/WEB-INF/jsp/register.jsp");
    }
}
public class RegisterController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("/WEB-INF/jsp/login.jsp");
    }
}

第二种方式基于注解:

@Controller
public class IndexController {
    // 处理请求的方法
    @RequestMapping("/login")
    public void add(){
    return "index";
      }
}

xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 使用扫描机制扫描控制器类,控制器类都在controller包及其子包下 -->
    <context:component-scan base-package="controller" />
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

6.编写springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- LoginController控制器类,映射到"/login" -->   
    <bean name="/login" class="controller.LoginController"/>   
    <!-- LoginController控制器类,映射到"/register" -->
    <bean name="/register" class="controller.RegisterController"/>
</beans>

7.配置视图解析器

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>

6.springMVC常用注解
1.@Controller:

用于定义控制器类

2.@ResponseBody:

表示方法的返回结果直接写入HTTP response body中

3.@PathVariable:

获取路径参数

4.@RequestParam:
用在方法的参数前面

5.@RequestBody

6.@RestController:

是@Controller和@ResponseBody的合集

7.@RequestMapping:

提供路由信息,负责URL到Controller中的具体函数的映射

8.@GetMapping:

是@RequestMapping(method = RequestMethod.GET)的缩写。不支持@RequestMapping的自定义属性。

9.@PostMapping:

是@RequestMapping(method = RequestMethod.POST)的缩写。不支持@RequestMapping的自定义属性。

10.@ControllerAdvice:统一处理异常。

11.@ExceptionHandler:用在方法上表示遇到这个异常就执行以下方法。

二、 struts2
Struts2 是 Apache 软件组织推出的一个相当强大的 Java Web 开源框架,本质上相当于一个 servlet。Struts2 基于 MVC 架构,框架结构清晰。通常作为控制器(Controller)来建立模型与视图的数据交互,用于创建企业级 Java web 应用程序

1.Struts2处理用户请求的完整流程
在这里插入图片描述
1)首先客户端浏览器发送一个请求(HttpServletRequest)。

2)接着程序会调用 StrutsPrepareAndExecuteFilter,然后询问 ActionMapper 这个请求是否需要调用某个 Action。

3)如果 ActionMapper 决定需要调用某个 Action,StrutsPrepareAndExecuteFilter 会把请求的处理交给 ActionProxy。

4)ActionProxy 通过配置管理器(Configuration Manager)从配置文件(struts.xml)中读取框架的配置信息,从而找到需要调用的 Action 类。

5)ActionProxy 会创建一个 ActionInvocation 的实例。

6)ActionInvocation 使用命名模式调用 Action,在调用 Action 前,会依次调用所有配置的拦截器(Intercepter1、Intercepter2……)。

7)一旦 Action 执行完,则返回结果字符串,ActionInvocation 就会负责查找结果字符串对应的 Result,然后执行这个 Result。通常情况下 Result 会调用一些模板(JSP 等)呈现页面。

8)产生的 Result 信息返回给 ActionInvocation,在此过程中拦截器会被再次执行(顺序与 Action 执行之前相反)。

9)最后产生一个 HttpServletResponse 的响应行为,通过 StrutsPrepareAndExecuteFilter 反馈给客户端。

2.创建struts简单项目
1.新建web工程
2.引入相应jar包
3.编写web.xml

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    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">
    <!-- 配置Struts2核心过滤器 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

4.创建Action类

public class HelloWorldAction extends ActionSupport {
    public String execute() throws Exception {
        return SUCCESS;
    }
}

5.编写struts配置文件struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定 Struts2 配置文件的 DTD 信息 -->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- Struts2配置文件的根元素 -->
<struts>
    <!-- Struts2的Action必须放在指定的包空间下定义 -->
    <package name="hello" namespace="/" extends="struts-default">
        <!-- 定义 action,该 action 对应的类为 action.HelloWorldAction 类-->
        <action name="helloWorld" class="action.HelloWorldAction">
            <!-- 定义处理结果和视图资源之间的映射关系 -->
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

6.创建视图首页文件

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>首页</title>
</head>
<body>
    <a href="${pageContext.request.contextPath }/helloWorld.action">
            第一个 Struts2 程序!
    </a>
</body>
</html>

7.创建返回页面

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>成功页面</title>
</head>
<body>
    您的第一个小程序执行成功,欢迎来到Struts2的世界!
</body>
</html>

3.struts.xml配置文件详解

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!--<constant>元素用常量的配置-->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <!--<package>元素用于包配置-->
    <package name="default" namespace="/" extends="struts-default">
        <!--配置Action-->
        <action name="index" class="Xxx"/>
            <!--配置Result-->
            <result type="dispatcher">
                <param name="location">/index.jsp</param>
            </result>
        </action>
    </package>
    <!-- <include>元素用于包含配置 -->
    <include file="example.xml"/>
</struts>

<struts> 元素是文件的根元素,所有其他元素都放在 <struts></struts> 中。
<constant> 元素用于进行常量配置。
<package> 元素用于进行包配置,在 Struts2 框架中,包用于组织 Action 和拦截器等信息,每个包都是由零个或多个拦截器以及 Action 所组成的集合。
<include> 元素用于在一个 struts.xml 配置文件中包含其他的配置文件。

4.Action控制类

public interface Action {
    //定义Action接口中包含的一些结果字符串
    public static final String SUCCESS="success";
    public static final String NONE="none";
    public static final String ERROR="error";
    public static final String INPUT="input";
    public static final String LOGIN="login";
    //定义处理用户请求的execute()方法
    public String execute() throws Exception;
}

由于 Xwork 的 Action 接口十分简单,为开发者提供的帮助较小,所以在实际开发过程中,通常都是采用继承 ActionSupport 类的方式创建 Action。

ActionSupport 是 Action 接口的默认实现类,所以继承 ActionSupport 就相当于实现了 Action 接口。除 Action 接口以外,ActionSupport 类还实现了 Validateable、ValidationAware、TextProvider、LocaleProvider 和 Serializable 等接口,这为用户提供了更多的功能。

5.使用通配符
由于在一个 Action 类中可能有多个业务逻辑处理方法,在配置 Action 时,就需要使用多个 元素。在实现同样功能的情况下,为了减少 struts.xml 配置文件的代码量,可以借助于通配符映射信息。

<package name="user" namespace="/user" extends="struts-default">
    <action name="userAction_*" class="com.mengma.action.UserAction" method="{1}">
        <result>/index.jsp</result>
    </action>
</package>

6.通过 ActionContext 访问
ActionContext 是 Action 执行的上下文对象,在 ActionContext 中保存了 Action 执行所需要的所有对象,包括 request、session 和 application 等。

1.void put(String key, Object value) 将 key-value 键值对放入 ActionContext 中,模拟 Servlet API 中的 HttpServletRequest 的 setAttribute() 方法;
2.Object get(String key) 通过参数 key 查找当前 ActionContext 中的值;
3.Map<String, Object> get Application() 返回一个 Application 级的 Map 对象;
4.static ActionContext getContext() 获取当前线程的 ActionContext 对象;
5.Map<String, Object> getParameters() 返回一个包含所有 HttpServletRequest 参数信息的 Map 对象;
6.Map<String, Object> getSession() 返回一个 Map 类型的 HttpSession 对象。

7.通过 ServletActionContext 访问
除了通过 ActionContext 类访问 Servlet API 以外,Struts2 框架还提供了 ServletActionContext 类访问 Servlet API,该类中的方法都是静态方法。
1.static PageContext getPageContext() 获取 Web 应用的 PageContext 对象;
2.static HttpServletRequest getRequest() 获取 Web 应用的 HttpServletRequest 对象;
3.static HttpServletResponse getResponse() 获取 Web 应用的 HttpServletResponse 对象;
4.static ServletContext getServletContext() 获取 Web 应用的 ServletContext 对象。

8.OGNL
OGNL 的全称是“Object-Graph Navigation Language”,即对象图导航语言,它是一种功能强大的开源表达式语言。使用这种表达式语言可以通过某种表达式语法存取 Java 对象的任意属性,调用 Java 对象的方法,以及实现类型转换等。

OGNL 具有以下特点。
1.支持对象方法调用。如 objName.methodName()。
2.支持类静态方法调用和值访问,表达式的格式为 @[类全名(包括包路径)]@[方法名|值名]。如 @java.lang.String@format(‘fruit%s’,‘frt’)。
3.支持赋值操作和表达式串联。如 price=100,discount=0.8,在方法 calculatePrice() 中进行乘法计算会返回 80。
4.访问 OGNL 上下文(OGNL context)和 ActionContext。
操作集合对象。

9.值栈(ValueStack)
值栈(ValueStack)就是 OGNL 表达式存取数据的地方。在一个值栈中,封装了一次请求所需要的所有数据。

在使用 Struts2 的项目中,Struts2 会为每个请求创建一个新的值栈,也就是说,值栈和请求是一一对应的关系,这种一一对应的关系使值栈能够线程安全地为每个请求提供公共的数据存取服务。

9.1值栈的作用
值栈可以作为一个数据中转站在前台与后台之间传递数据,最常见的就是将 Struts2 的标签与 OGNL 表达式结合使用。值栈实际上是一个接口,在 Struts2 中利用 OGNL 时,实际上使用的就是实现了该接口的 OgnlValueStack 类,这个类是 OGNL 的基础。

9.2值栈的生命周期
值栈贯穿整个 Action 的生命周期,每个 Action 类的对象实例都拥有一个 ValueStack 对象,在 ValueStack 对象中保存了当前 Action 对象和其他相关对象。

Struts2 框架把 ValueStack 对象保存在一个名为 struts.valueStack 的 request 属性中,也就是说,值栈与 Action 的生命周期一致。值栈的生命周期随着 request 的创建而创建,随着 request 的销毁而销毁。

9.3值栈的获取方式
要获取值栈中存储的数据,首先应该获取值栈。值栈的获取有两种方式,具体如下。
1)在 request 中获取值栈
ValueStack 对象在 request 范围内的存储方式为 request.setAttribute(“struts.valueStack”,valuestack),可以通过如下方式从 request 中取出值栈的信息。
//获取 ValueStack 对象,通过 request 对象获取

ValueStack valueStack = (ValueStack)ServletActionContext.getRequest()
            .getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

在上述示例代码中,ServletActionContext.STRUTS_VALUESTACK_KEY 是 ServletActionContext 类中的常量,它的值为 struts.valueStack。
2)在 ActionContext 中获取值栈
在使用 Struts2 框架时,可以使用 OGNL 操作 Context 对象从 ValueStack 中存取数据,也就是说,可以从 Context 对象中获取 ValueStack 对象。实际上,Struts2 框架中的 Context 对象就是 ActionContext。

ActionContext 获取 ValueStack 对象的方式如下所示:
//通过 ActionContext 获取 valueStack 对象

ValueStack valueStack = ActionContext.getContext().getValueStack();

ActionContext 对象是在 StrutsPrepareAndExcuteFilter 的 doFilter() 方法中被创建的,在源码中用于创建 ActionContext 对象的 createActionContext() 方法内可以找到获取的 ValueStack 对象的信息。

方法中还有这样一段代码:
ctx=new ActionContext(stack.getContext());

从上述代码中可以看出,ValueStack 对象中的 Context 对象被作为参数传递给了 ActionContext 对象,这也就说明 ActionContext 对象中持有了 ValueStack 对象的引用,因此可以通过 ActionContext 对象获取 ValueStack 对象。

9.4Struts2值栈内部结构
ValueStack 对象的内部有两个逻辑部分。
ObjectStack(对象栈):是 CompoundRoot 类型,用 ArrayList 定义,Struts2 把动作和相关对象压入 ObjectStack 中。
ContextMap(Map 栈):是 OgnlContext 类型,是一个 Map 集合,Struts2 把各种各样的映射关系(一些 Map 类型的对象)压入 ContextMap 中。

三、springmvc和struts2的区别
转载至:https://blog.csdn.net/wuli_qiyou/article/details/79510822

一、框架机制
1、Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。
2、Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

二、拦截机制
1、Struts2
a、Struts2框架是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype(否则会出现线程并发问题),然后通过setter,getter吧request数据注入到属性。
b、Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。
c、Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了

2、SpringMVC
a、SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。
b、在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。

三、性能方面
SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。而Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,所以,SpringMVC开发效率和性能高于Struts2。

四、拦截机制
Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。

五、配置方面
spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
SpringMVC可以认为已经100%零配置。

六、设计思想
Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。

七、集成方面
SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。

发布了16 篇原创文章 · 获赞 12 · 访问量 154

猜你喜欢

转载自blog.csdn.net/qq_36435947/article/details/105030189
今日推荐