• Java框架之Spring MVC(一)


    一、Spring简介

    Spring MVC是当前最优秀的 MVC 框架,自从Spring 2.5 版本发布后,由于支持注解配置,易用性有了大幅度的提高。Spring 3.0 更加完善,实现了对 Struts 2 的超越。现在越来越多的开发团队选择了Spring MVC。

    1)Spring3 MVC使用简单,学习成本低。学习难度小于Struts2,Struts2用不上的多余功能太多

    2)Spring3 MVC很容易就可以写出性能优秀的程序,Struts2要处处小心才可以写出性能优秀的程序(指MVC部分)

    3)灵活

    √让我们能非常简单的设计出干净的Web层和薄薄的Web层;

    √进行更简洁的Web层的开发;

    √天生与Spring框架集成(如IoC容器、AOP等);

    √提供强大的约定大于配置的契约式编程支持;

    √能简单的进行Web层的单元测试;

    √支持灵活的URL到页面控制器的映射;

    √非常容易与其他视图技术集成,如Velocity、FreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用);

    √非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API;

    √提供一套强大的JSP标签库,简化JSP开发;

    √支持灵活的本地化、主题等解析;

    √更加简单的异常处理;

    √对静态资源的支持;

    √支持Restful风格

    前端控制器是DispatcherServlet;

    应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;

    页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO类);

    支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;

    提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

    二、配置核心控制器

    1) 导包,配置环境

    aopalliance-1.0.jar

    bean-validator.jar

    commons-fileupload-1.2.2.jar

    commons-io-2.1.jar

    commons-logging-1.2.jar

    javax.servlet.jsp.jstl-1.2.1.jar

    jsp-api-2.1.jar

    jstl-1.2.jar

    jstl-api-1.2.jar

    mysql-connector-java-5.1.7-bin.jar

    servlet-api-2.5.jar

    spring-aop-4.1.4.RELEASE.jar

    spring-beans-4.1.4.RELEASE.jar

    spring-context-4.1.4.RELEASE.jar

    spring-core-4.1.4.RELEASE.jar

    spring-expression-4.1.4.RELEASE.jar

    spring-web-4.1.4.RELEASE.jar

    spring-webmvc-4.1.4.RELEASE.jar

    standard-1.1.2.jar

    2)

    配置核心控制器

    配置处理器映射器 handler Mapping

    配置处理器适配器 handler Adapter

    配置视图解析器

    2.1 配置核心控制器

    在 web.xml 中

    <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--  在 spring-webmvc-4.1.4.RELEASE.jar 下 -->
    <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value> //手动指定配置文件的路径
    </init-param>
    </servlet>
    <servlet-mapping>
            <servlet-name>springmvc</servlet-name> 
            <url-pattern>/</url-pattern> // 可以写成*.do,*.action,但不能写成杠* 
    </servlet-mapping>

    说明:

    1 默认情况下,加载配置文件是 WEB-INF/servlet名称-servlet.xml   //springMVC-servlet.xml

    2 如果想指定配置文件的路径,可以加入参数进行指写

    三、配置

    配置处理器映射器, 配置处理器适配器,  配置视图解析器 (即配置主文件)

    <!--  配置处理器映射器 handler Mapping -->
    <bean name="/search_all" class="cat.controller.UserAction"  />
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />  
             
    <!--   配置处理器适配器 handler Adapter -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
               
    <!--   配置视图解析器  -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
    //Action 中的方法
    public class UserAction implements Controller {  //要实现 Controller
           public ModelAndView handleRequest(HttpServletRequest request,
                        HttpServletResponse response) throws Exception {
                        UserDao dao=new UserDao();
                        List<UserInfo> userList=dao.getAllUser();
                        
                        ModelAndView mv=new ModelAndView();
                        mv.addObject("userList", userList); //相当于request.setAttribute();
                        mv.setViewName("user_manage.jsp");
                        
                        return mv;
                    } 
                }

    访问的时候 http://localhost:8080/springmvc/search_all

    附: user_manage.jsp

    <body>
    <c:forEach var="u" items="${userList }">
       ${u.id } | ${u.userName } | ${u.password }  <br />
    </c:forEach>
    </body>

    # Default implementation classes for DispatcherServlet s strategy interfaces.
    # Used as fallback when no matching beans are found in the DispatcherServlet context.
    # Not meant to be customized by application developers.

    org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
    org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

    org.springframework.web.servlet.HandlerMapping=  //处理器映射器
    org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,
    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping //这个是3.1之前的
    //org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping 应该用这个才对

    org.springframework.web.servlet.HandlerAdapter=  //处理器适配器

    org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter  //这个是3.1之前的
    //org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 应该用这个才对

    org.springframework.web.servlet.HandlerExceptionResolver=
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

    org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

    org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

    org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

    使用注解的方式配置处理器映射器和处理器适配器

    1) 配置文件 springmvc-servlet.xml

    //开启扫描  
    <context:component-scan base-package="cat.controller" />
                    
    //开启注解配置 
    <mvc:annotation-driven />
                    
    /* 有了上面的配置,下面的就可以不写了
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
    */
                
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    //<property name="prefix"  value="/WEB-INF/jsp/" /> 
    <property name="prefix"  value="/" />
    <property name="suffix"  value=".jsp" />
    </bean>

    2)

    @Controller  //这里只能用 @Controller ,不能用 Service
    public class UserAction  {
    @RequestMapping("/search_all")  //请求的名称,最好和方法名相同
    public ModelAndView getAllUser(){
                                    UserDao dao=new UserDao();
                                    List<UserInfo> userList=dao.getAllUser();
                                    
                                    ModelAndView mv=new ModelAndView();
                                    mv.addObject("userList", userList); //相当于request.setAttribute();
                                    mv.setViewName("user_manage.jsp");
                                    
                                    return mv;
                                }
                         }

    五、@RequestMapping 注解, 和 Action中方法的返回值

    在上例中添加用主修改的功能

    1) @RequestMappingr 的说明

    @RequestMapping 用来将url 和方法名进行 映射 ,一个方法,对应一个url , 比如     @RequestMapping("/search_all") 后面可以加.action 

    可以用类,或方法上,用在类上,表示所有方法的根路径

    比如

    @RequestMapping("/user")  //写在类体上
    public class UserAction  {    ...  }

    RequestMappingr 注解有6个属性 value,method,consumes,produces,params,headers

    --value 指定请求的实际地址 -> @RequestMapping(value="/search_all")=@RequestMapping("/search_all")

    --method 指定请求的method类型 (GET,POST,PUT,DELETE等)

    例如

    @RequestMapping(value="/updateUser" ,method=RequestMethod.POST) 
    @RequestMapping(value="/updateUser" ,method={RequestMethod.POST,RequestMethod.GET}) 

    说明 如果请求类型不对则出现类似异常 Request method 'GET' not supported

    -- consumes:  指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

    -- produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

    -- params: 指定request中必须包含某些参数值时,才让该方法处理。 //实测发现如果指定了,不传将出错

    -- headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。

    2) Action中方法的返回值的说明

    -- ModelAndView

    -- String //如果返回的是String 类型,则代表返回的逻辑视图名称 (相当于struts2中的逻辑视图 )

    //例一
    @RequestMapping(value="/updateUser" ,method=RequestMethod.GET) 
    public String  updateUser(Model model){  //用model 进行传参
                                UserInfo user=new UserDao().getAdminById(4);
                                model.addAttribute("user", user);
                                return "user_edit";
                            }
    //例二 关于请求的转发和重定向
    @RequestMapping(value="/updateUser" ,method=RequestMethod.POST) //只有请求是get请求的时候才有效
    public String updateUserSubmit(){
                                System.out.println("-----"); 
                            //return "redirce:search_all" ;    //重定向 search_all是一个请求的名称
                                return "forward:search_all" ; 
                            }

    -- void

    //例子
    @RequestMapping(value="/udpateUserSubmit")
    public void udpateUserSubmit(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
                            /* response.sendRedirect("search_all"); //重定向到某个url
                             response.sendRedirect("success");  //404
                             request.getRequestDispatcher("/success.jsp").forward(request, response);*/
                             response.getWriter().print("<h1>哈哈哈,这样也可以</h1>");
                             response.getWriter().print( ""userName":"张三","password":"123""  );  //返回json数据
                        }

    六、参数绑定与值的传递

    页面请求发起的时候,如何把值传给Controller (//Action ),以及如何把模型数据进行传递

    1) 在 Controller 的形参上,可以直接定使用以下对象

    HttpServletRequest

    HttpServletResponse

    HttpSession

    Model //public abstract interface org.springframework.ui.Model

    MdelMap // org.springframework.ui.ModelMap

    Map<String ,Object>  //普通的map也可以,往这里放的值,最终就放在了作用域中,在页面就可以取出 ${key} ;

    2) 可以使用简单类型

    //例一
    @RequestMapping("/testParam") 
    public void testParam(String userName,String password,String note){
                            System.out.println(userName+":"+password+":"+note);
                        }
                    //本例的前提 参数名和请求传上来的参数名要一致
    //例二  @RequestParam 注解的作用
    @RequestMapping("/testParam2") 
    public String testParam2(
                             String userName, 
                             ModelMap mode,
                             @RequestParam("password") String pwd,
                             @RequestParam(value="age",required=true) int age,  //标明是必须的,如果不传将出错
                             @RequestParam(value="school",defaultValue="农业工程学院") String school)
                            {
                             System.out.println("userName:"+userName);
                             System.out.println("age:"+age);
                             System.out.println("school:"+school);
                             return "success";
                            }

    3) 关于pojo类型(就是bean)  

    只要表单元素的名字和方法的参数中的属性值相同却可。

    @RequestMapping(value="/updateUser",method=RequestMethod.POST)
    public String udpateUserSubmit(UserInfo user) {
                            System.out.println(user);  //这里接收的参数是pojo类型
                            new UserDao().updateUser(user);  
                            return "success";
                        }
    //user_edit.jsp
    <form action="${pageContext.request.contextPath }/updateUser" method="post">  //注意,提交方式是post
           id:   <input type="text" name="id" value="${user.id }" /> 
           账号: <input type="text" name="userName" value="${user.userName }" /> 
           密码: <input type="text" name="password" value="${user.password }" /> 
           备注:  <input type="text" name="note" value="${user.note }" /> 
           <input type=submit value="提交" />
    </form>

    附:

    处理乱码spring的过滤器

    <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
           <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>杠*</url-pattern>
    </filter-mapping>

    如果是get请求的乱码怎么处理?

    public String test(HttpServletRequest request){
                                            String userName=request.getParameter("userName");
                                            userName=new String(userName.getBytes("iso8859-1"),"utf-8");
                                      }
    //上例或 在tomcat 的配置文件中(server.xml中加入  useBodyEncodingForURI=ture )
    <Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" URIEncoding="utf-8" useBodyEncodingForURI=ture
    />

    4) 关于日期类型

    例: 在实体类中添加一个日期类型的字段

    private Date birthday;   //生成get set
    //在user_edit.jsp 页面上 加上字段   
    <input type="text" name="birthday" value="${user.birthday }" />  可以发现,在提交的时候出

    解决日期类型的问题有以下几个方式

    方式一:在实体类中加格式化注解

    @DateTimeFormat(pattern="yyyy-MM-dd")  //有效,简单
    private Date birthday;

    方式二:在控制器中加入一段数据绑定代码

    @InitBinder
    public void initBinder(WebDataBinder binder) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                dateFormat.setLenient(false);
                binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));   //true:允许输入空值,false:不能为空值
                }
                                    
    //此方式:对于某个Oontroller可以独立控制

    方式三:要向处理器适配器中注入自定义参数绑定组件

    5) 包装类型的pojo

    public class UserInfoCustom {
                                 private UserInfo user;  //包装一个pojo类型
                                 private String schoolName;  //get set 方法..
                                }

    user_add.jsp //用户添加页面

      <form action="${pageContext.request.contextPath }/addUser" method="post">
                               账号:    <input type="text" name="user.userName"  /> 
                               密码:     <input type="text" name="user.password"  /> 
                               备注:  <input type="text" name="user.note" /> 
                               学校:  <input type="text" name="schoolName" />   //注意
                                         <input type=submit value="提交" />
                                       </form>
                                                
                            //添加会员,用包装类型的pojo传值
                                @RequestMapping(value="/addUser",method=RequestMethod.POST)
                                public String addUser(UserInfoCustom info){
                                    System.out.println(info);
                                    //new UserDao().addUser(info)
                                    return "success";
                                }

    6) 数组类型的绑定

    user_manage.jsp

    <form action="${pageContext.request.contextPath }/deleUser" method="post">
    <c:forEach var="u" items="${userList }">
    <input type="checkbox" name="ids" value="${u.id } ">    ${u.id } | ${u.userName } | ${u.password }  <br />
    </c:forEach>
    <input type="submit" value="删除所选" >
    </form>

    控制层中业务方法

    @RequestMapping("/deleUser")
    public String delUsers(Integer [] ids){  //参数名要和页面中传的参数名相同
                           for(Integer id:ids){
                                        System.out.println(id);
                                        }
                           //new UserDao().deleteUsers(ids);
                                        return "success";
                           }
                             
    //附:也可以如下
    @RequestMapping("/deleUser")
    public String delUsers(HttpServletRequest request){
                           String [] ids=request.getParameterValues("ids");
                           //new UserDao().deleteUsers(ids);
                           return "success";
    }

    7) List 类型的数据绑定 (比如批量更新)

    包装类型

    public class UserInfoCustomL {
                                  private List<UserInfo> userList;  //生成get set 
                          }            
  • 相关阅读:
    实现第三方系统单点登录
    python爬虫
    webot设备motor的api
    webots学习
    python学习算术运算
    python快捷键与命令函数
    python学习构造和析构
    python学习对象相关的bif
    python学习对象:拾遗
    matlab基础知识
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/8158993.html
Copyright © 2020-2023  润新知