zoukankan      html  css  js  c++  java
  • Java Spring MVC

    Spring MVC的实现包括 实现Controller类和基于注解的Controller RequstMapping方式

    依赖:

      <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.3.1.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>4.3.1.RELEASE</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
    Source

    基于Controller接口的MVC

    这里用到了一个通用接口Controller, Controller的实现类将作为spring的bean被加载到classpath中,在配置文件中定义uri 和bean之间的对应关系。 配置文件的加载在Web.xml中指定 同时Web.xml还负责定义全局的Dispatcher Servlet来接受根 /的 所有请求。

    依赖:

    1. Controller接口:

    Package: org.springframework.web.servlet.mvc;

    方法: ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;

    实现

    public class ProductInputController2 implements Controller {
    
     // GET 方法 返回表单
     /// 这里返回ModelAndView的示例 参数代表JSP的名字
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            return new ModelAndView("ProductForm");
        }
    }
    
    
    public class ProductSaveController2 implements Controller {
     
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            productForm form = new productForm(0,httpServletRequest.getParameter("name"), Float.parseFloat(httpServletRequest.getParameter("price")));
            product p = new product(form.get_id(),form.get_name(),form.get_price());
            
            // 这里设置request的对象参数。 将来会在ProductDetails的view中用于显示对象属性
            return new ModelAndView("ProductDetails","product",p);
        }
    }
    

    2. 配置文件:

    上面定义了两个controller的行为和数据,那么下一步就是定义请求uri和Controler的对应。这里在配置文件中的bean定义来实现

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      /// 对应的Controller此处定义为Bean 对应的Name为path. 
        <bean name="/product_input.action" class="controller.ProductInputController2"></bean>
        <bean name="/product_save.action" class="controller.ProductSaveController2"></bean>
    /// View Resolver使的我们在定义ModelAndview()实例的时候不用再指定path和后缀
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    </beans>
    

     

    3. 配置文件的加载:

    通过Web.xml 中自定义DispatcherServlet的方式来实现。

    Servlet: org.springframework.web.servlet.DispatcherServlet 专门用来处理根请求的分发

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
        <servlet>
            <servlet-name>controllerServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-web.xml</param-value>
            </init-param>
    
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>controllerServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    基于注解的MVC

    基于注解的MVC主要解决的问题是一个文件定义一个controller(@Controller)多个request uri(@RequestMapping)。

    并且uri和handlerRequest的影射关系不再需要在配置文件中指定。 在Controller的方法中就指定就可以了。

    当然controller还是作为bean还是要借助配置文件被加载到classpath中的。类似于<context: component-scan />会加载所有controller文件并且是单例的

    这里介绍一个例子:

    1. Model: 这里定义一个将用于UI 上现实的Model(注意这个 Model的属性名称 必须和UI 上的控件Name对应,这样能实现对象与UI 的绑定)

    public class productForm {
        private int id;
        private String name;
        private float price;
    
        public float getPrice() {
            return price;
        }
    
        public void setPrice(float price) {
            this.price = price;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public productForm(int id, String name, float price){
            this.id =id;
            this.name =name;
            this.price =price;
    
        }
    
        public productForm(){}
    }
    

     2. View: 输入jsp 页面定义了上面Model对应的组建(通过Name属性)。这样在POST 方法提交后可以在Controller方法的参数中获取对象

    用于输入的表单

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>Add Product Form</title>
    <style type="text/css">@import url(css/main.css);</style>
    </head>
    <body>
    
    <div id="global">
    <form action="product_save.action" method="post">
        <fieldset>
            <legend>Add a product</legend>
                <p>
                    <label for="name">Product Name: </label>
                    <input type="text" id="name" name="name" 
                        tabindex="1">
                </p>
                <p>
                    <label for="description">Description: </label>
                    <input type="text" id="description" 
                        name="description" tabindex="2">
                </p>
                <p>
                    <label for="price">Price: </label>
                    <input type="text" id="price" name="price" 
                        tabindex="3">
                </p>
                <p id="buttons">
                    <input id="reset" type="reset" tabindex="4">
                    <input id="submit" type="submit" tabindex="5" 
                        value="Add Product">
                </p>
        </fieldset>
    </form>
    </div>
    </body>
    </html>
    原码

    用于确认信息的表单

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>Save Product</title>
    </head>
    <body>
    <div id="global">
        <h4>The product has been saved.</h4>
        <p>
            <h5>Details:</h5>
            Product Name: ${product.name}<br/>
            Price: $${product.price}
        </p>
    </div>
    </body>
    </html>
    Source

    3. Controller:@Contoller注解用于定义Controller bean, 这个属性用于在配置文件的 <context: component-scan />

    @RequestMapping()用于定义请求地址和handler之间匹配。 Value=""用于标示请求的uri. Method用于标示请求的方式

    GET and POST

    import model.product;
    import model.productForm;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    /**
     * Created by ygshen on 7/18/16.
     */
    @Controller
    public class ProductController {
    
        private static Log logger = LogFactory.getLog(ProductController.class);
    
     // http://localhost:8080/springmvc/product_form2.action的时候将访问到这个method
        @RequestMapping(value = "/product_form2.action")
        public String productForm(){
    
            logger.info("Request the product input form ");
            return "ProductForm";
        }
     // http://localhost:8080/springmvc/product_save.action的时候将访问到这个method
    // 这里的参数 productForm能够自动根据输入表丹的属性初始化对象。 Model用于传递对象给下一个View。 类似与Request.setAttribute("product",p). 
        @RequestMapping(value = "/product_save.action", method = {RequestMethod.POST, RequestMethod.PUT})
        public String saveForm(productForm form, Model model){
            logger.info("request the product save post method");
            logger.info("Product Name: "+ form.getName()+ ". Product price: "+ form.getPrice());
    
            product p = new product(form.getId(),form.getName(),form.getPrice());
            model.addAttribute("product",p);
            return "ProductDetails";
        }
    }
    

    4. Controller的发现:

    之前使用的<bean></bean>定义一个类是bean ,这里因为有@Controller 的存在已经证明是bean了,需要作的是扫描到他。
    <context:component-scan /> 就是这个作用。

    <?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:p="http://www.springframework.org/schema/p"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
           <context:component-scan base-package="web.controller" />
    
        <mvc:annotation-driven></mvc:annotation-driven>
           <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  <property name="prefix" value="/WEB-INF/jsp/"></property>
                  <property name="suffix" value=".jsp"></property>
           </bean>
    </beans>

    4. Controelr配置文件的定义:

    web.xml中定义DispactcherServlet处理所有请求,并且Servlet中指定配置文件。 内容就是3中指定的。

    Formatter、Converter

    1. Converter接口

    public interface Converter<S, T> {
        T convert(S var1);
    }
    

     S是原数据类型,T是转换目标

    如 日期输入框输入的都是字符串类型,Converter可以负责自动转换成日期类型 而不必在Controller里用代码判断和转换

    public class StringToDateConverter implements Converter<String, Date> {
        public Date convert(String dateString) {
            try {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
                simpleDateFormat.setLenient(false);
                return simpleDateFormat.parse(dateString);
            }
            catch (ParseException exception){
                throw new IllegalArgumentException("Invalid date formate"+ datePattern);
            }
        }
    
    
        private String datePattern;
    
        public StringToDateConverter(String _datePattern) {
            datePattern=_datePattern;
        }
    }
    View Code
    <form:errors path="publishTime" cssClass="error"></form:errors>
    <label for="publishTime">PublishTime:</label>
    <form:input path="publishTime" id="publishTimes" type="text"></form:input>

    这里Input输入的是字符串,但是因为Converter的存在会自动实现字符串转成目标(Path=publishTime在Model中的属性被定义成 Date类型)类型。

    前提是Converter必须在 configure文件中注册了

        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <bean class="Formatters.StringToDateConverter">
                        <constructor-arg type="java.lang.String" value="MM-dd-yyyy"></constructor-arg>
                    </bean>
                </set>
            </property>
        </bean>
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    

    2. Formatter: 作用和Converter相同,但是 元数据类型只能是String.

    public interface Formatter<T> extends Printer<T>, Parser<T> {
    }
    

     另外 Formatter的注册方式如下

       <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="formatters">
                <set>
                    <bean class="Formatters.StringToDateConverter">
                        <constructor-arg type="java.lang.String" value="MM-dd-yyyy"></constructor-arg>
                    </bean>
                </set>
            </property>
        </bean>
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    
  • 相关阅读:
    JS之函数声明与表达式
    任重道远!
    Java_Notes01
    Android_Application Fundamentals
    Android_Activity
    Android
    Linux下的实模式和保护模式
    spring注解原理
    开启aix SFTP日志 是否和链接SFTP有关呢
    Apache版本兼容性问题
  • 原文地址:https://www.cnblogs.com/ygshen/p/5701442.html
Copyright © 2011-2022 走看看