springMVC

JSP Model 1
    jsp负责显示/逻辑控制
JSP Model 2
    jsp负责显示,servlet负责逻辑

处理流程
发送请求->委托请求给处理器->调用业务对象->返回数据模型
->返回ModelAndView->渲染视图->返回控制->产生响应
-----------------------------------------------
可以用form标签
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

DispatcherServlet
Handler
  @controller     //标记控制器类
  @RequestMapping(value,method,param)  //请求映射路径
  @PathVariable  //得到请求url地址中的参数
  @RequestParam  //得到请求页面标签的name值
  @ResponseBody  //把对象放进body作用域
方法的返回值
  ModelAndView
  Model
  View        
  String   //返回逻辑视图名
  Object    
  void



============================================================
Spring MVC


BeanNameUrlHandlerMapping------------------
spring配置(引入schema/mvc)
          <!--默认 可以不写  引入这个类,页面映射RequestMapping要写在这个配置文件中-->
1.  <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
2.  使用注解的方式(后面会讲到)

<!-- MyController这个类继承了AbstractController并重写其方法返回jsp文件名 -->
<!-- 页面访问url:localhost:8080/项目名/welcom -->
<bean name="/welcome" class="com.pp.controller.MyController"/>
//return new ModelAndView("welcome");
 
<!-- 返回的是个ModelAndView对象,会找到这个InternalResourceViewResolver类 -->
<!-- 通过前缀,后缀和返回结果拼接成路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/"></property>
  <property name="suffix" value=".jsp"></property>
</bean>

******************************************************************************
Web.xml配置信息

  <!-- 处理字符编码的filter -->


  <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>
      <init-param>
          <param-name>forceEncoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>CharacterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:DispatcherServlet-servlet.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>DispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>
 
<!--
1. servlet的name:DispatcherServlet要和springMVC配置文件名一样,如DispatcherServlet-servlet.xml
2. Web容器启动时,按照优先级顺序加载<load-on-startup>的参数越小级别越高,同时写在<init-param>标签下才不会报错
-->
******************************************************************************

<context:component-scan base-package="com.pp.controller"></context:component-scan>
<mvc:annotation-driven/>

<!--
    在springMVC配置文件中 使用annotation注解的方式,完成映射
    扫描包下所有spring注解
-->
******************************************************************************

@Controller  //标记为控制器
public class MyAnnotationController {
    @RequestMapping(value="/welcome2")   //标记请求映射的方法
    public String hello(){
        System.out.println("AnnotationController");
        return "welcome";
    }
}


//DefaultAnnotationHandlerMapping
  将请求映射给使用 RequestMapping注解的控制器和控制方法


ModelAndView----->

@Controller
@RequestMapping(value="user/")
public class MyController  {
    
//    @RequestMapping(value="/hello")
//    public String handleRequestInternal(HttpServletRequest request) {
//        List<User> userList=new ArrayList<User>();
//        userList.add(new User("王","111","mgr1"));
//        userList.add(new User("刘","222","mgr2"));
//        userList.add(new User("张","333","mgr3"));
//        request.setAttribute("userList", userList);
//        
//        return "welcome";
//    }
    @RequestMapping(value="/list",method=RequestMethod.GET)
    public ModelAndView handleRequestInternal(HttpServletRequest request) {
        Map<String,User> userList=new HashMap<String, User>();
        userList.put("1", new User("王","111","mgr1"));
        userList.put("2", new User("刘","222","mgr2"));
        userList.put("3", new User("张","333","mgr3"));
        System.out.println("success!");
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("userList", userList);
        modelAndView.setViewName("userList");
        return modelAndView;
    }
}

//<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>

<context:component-scan base-package="com.pp"></context:component-scan>    

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

http://localhost:8090/SpringMVC2/user/list

==================================================
jsr303 服务器端验证

model:
@NotEmpty(message="用户名不能为空")
@Size(max=10,min=5,message="长度在5-10位")
@Email(message="输入正确的邮箱格式")

controller:
@RequestMapping(value="/add",method=RequestMethod.POST)
    public String hello2(@Validated User users,BindingResult bindingResult){
        if(bindingResult.hasErrors())
            return "user/adduser";
        userList.put(users.getUid(), users);
        return "redirect:userlist";
}

jsp:打印错误信息
<form:errors path="uname"/>

跳到目标详情信息====================================

@RequestMapping(value="/view/{id}/{id2}",method=RequestMethod.GET)
    public String userView(@PathVariable(value="id") String id,@PathVariable(value="id2") String id2,Model model){
        model.addAttribute(userList.get(Integer.valueOf(id)));
        System.out.println(id2);
        return "user/view";
}
1.注解的value值里参数是{},不是${EL表达式}
2.从页面的a标签传入的参数是string类型,map的key是Integer,要记得转换
3.参数注解PathVariable取地址里的参数
4.页面参数的注解是RequestParam


********************
关于控制器的返回路径问题

配置文件中:
<property name="prefix" value="/WEB-INF/jsp/"></property>  前缀
<property name="suffix" value=".jsp"></property>       后缀

return "user/view"             //逻辑视图名,文件名
return "redirect:/user/userlist" //重定向,从根开始算路径(定在了/jsp/),是基于页面的当前路径继续叠加
例如:
return "redirect:user/userlist"
http://localhost:8090/SpringMVC1/user/userlist 用户列表url
http://localhost:8090/SpringMVC1/user/3/user/userlist 删除第三条失败,跳转404

正确写法:return "redirect:/user/userlist"
*****************
创建一个类UserException去继承RunTimeException 有继承的构造方法

controller//抛出异常
throw new UserException("用户名或密码错误");

//把异常放进request作用域
@ExceptionHandler(value=UserException.class)
public String UserException(UserException e,HttpServletRequest httpServletRequest){
    httpServletRequest.setAttribute("e", e);
    return "user/error";
}
    
//页面从request作用域里去到报错信息打印
jsp:
<h2>${e.message }</h2>



-----------------------------------------------------------
全局异常
springMVC配置文件中引入
org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类

<property name="exceptionMappings">
    <props >
         <prop key="com.pp.controller.UserException">user/error</prop>
    </props>
</property>

//Navigate-Open Type查找引入的类名可以看源码,得到全路径(myeclipse)

jsp:${exception.message}



-------------------------------------------------
配置静态文件资源访问 springMVC中无法直接访问静态文件 需要映射成url进行访问
<mvc:resources location="/statics/" mapping="/statics/**" />
**文件夹及其子文件夹下的文件
href="<%=request.getContextPath()%>/statics/css/main.css"
************************************************************
多文件上传 (单文件上传去掉数组和遍历就可以) 需要jar包fileupload/io  

完整的spring配置文件:
<?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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        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">
        
   <!--   <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
          
    <bean name="/welcome" class="com.pp.controller.MyController"/>
         -->
         
     <context:component-scan base-package="com.pp"></context:component-scan>
     <mvc:annotation-driven/>
       

     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
            
     </bean>
     
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
         <property name="exceptionMappings">
             <props >
                 <prop key="com.pp.controller.UserException">error</prop>
                 
             </props>
         </property>
     </bean>
     

  <!-- 配置文件上传主要从这开始 -->
     <context:component-scan base-package="org.springframework.web.fileupload" />  
      
    <!-- 配置文件上传 MultipartResolver -->
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <property name="maxUploadSize" value="100000"></property>
     </bean>
     
     
     
     
     
        
</beans>

 


controller中:

//单文件上传

//多文件上传
@RequestMapping(value = "/add", method = RequestMethod.POST)
    public String handleRequestInternal2(@Validated User user,
            BindingResult bindingResult, @RequestParam MultipartFile attach,
            HttpServletRequest httpServletRequest) {
        if (bindingResult.hasErrors()) {
            return "user/addUser";
        }
     
            if (!attach.isEmpty()) {

       //得到上传文件的存放位置
                String fileuploadpath = httpServletRequest.getSession() .getServletContext().getRealPath("/statics/upload/");

      //得到项目路径+  反斜杠自适应(window系统,linux系统 的反斜杠不一样) +系统时间(可以不加) + 原始文件名
                File saveFile = new File(fileuploadpath + File.separator+ System.currentTimeMillis() +attach.getOriginalFilename());
                try {

      //上传文件   参数1: 需要上传目标文件的输入流  参数2: File对象
                    FileUtils.copyInputStreamToFile(attach.getInputStream(), saveFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
       
        userList.put(user.getUid(), user);
        return "redirect:list";
    }


//多文件上传
@RequestMapping(value = "/add", method = RequestMethod.POST)
    public String handleRequestInternal2(@Validated User user,
            BindingResult bindingResult, @RequestParam MultipartFile[] attachs,
            HttpServletRequest httpServletRequest) {
        if (bindingResult.hasErrors()) {
            return "user/addUser";
        }
        for (MultipartFile attach : attachs) {
            if (!attach.isEmpty()) {
                String fileuploadpath = httpServletRequest.getSession()
                        .getServletContext().getRealPath("/statics/upload/");
                File saveFile = new File(fileuploadpath + File.separator
                        + System.currentTimeMillis()
                        + attach.getOriginalFilename());
                try {
                    FileUtils.copyInputStreamToFile(attach.getInputStream(),
                            saveFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        userList.put(user.getUid(), user);
        return "redirect:list";
    }

jsp页面中---------
    attachs:<input type="file" name="attachs" /><br>
    attachs:<input type="file" name="attachs" /><br>
    attachs:<input type="file" name="attachs" /><br>




************************************************************


注解属性 param的作用
带了参数属性的  访问url后面就要带指定的参数  不然调用不到这个方法


url:http://localhost:8090/SpringMVC2/user/view/2?hh

@RequestMapping(value="/view/{id}",params="hh",method=RequestMethod.GET)
@ResponseBody
public User userView(@PathVariable String id){
    return userList.get(Integer.valueOf(id));
}



 

posted @ 2017-09-23 23:49  m97i  阅读(185)  评论(0编辑  收藏  举报