Spring MVC

Spring MVC

1 springMVC简介

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1,Struts2等。

 

Web层框架:springMVC、Struts(struts1、webwork、struts2、JSF(sun公司的实现--JSF,Apache的实现 MyFaces,...))

2 springMVC的主要作用

   1 处理数据

   2 控制跳转

   3 调用后台代码

   4 异常处理

   5 国际化

   ...

3 使用springMVC

3.1 添加jar包

3.2 配置核心控制器

    web.xml 添加核心控制器的配置

<servlet>

   <servlet-name>first</servlet-name>

     <servlet-class>

org.springframework.web.servlet.DispatcherServlet   </servlet-class>

        <init-param>

     <param-name>contextConfigLocation</param-name>

     <param-value>/WEB-INF/spring-servlet.xml</param-value>

     </init-param>

     <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

         <servlet-name>first</servlet-name>

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

    </servlet-mapping>

 

配置说明:

   DispatcherServlet 核心控制器类

 

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/spring-servlet.xml</param-value>

</init-param>

     指定springMVC的配置文件

     注意:可以不指定springMVC的配置文件,当不指定时,配置文件默认为

          <servlet-name>first</servlet-name>的配置名字

加上-servlet。即为 first-servlet.xml

 

3.3 springMVC配置文件

存放位置: WEB-INF下。

由于springMVC属于spring的一部分,因此springMVC的配置文件,就是一个spring的配置文件。

 

主要配置内容:

       启动spring的注解

              <context:annotation-config />

         启动bean扫描

              <context:component-scan base-package="web.controller" />

         启动spring MVC 注解方式

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

         <mvc:annotation-driven />

4 控制器(Controller)

   springMVC的控制器类可以是一个POJO(不需要继承和实现接口)

4.1 控制器添加注解说明

4.1.1 @Controller

        添加在类名上,说明这个类为springMVC的Controller

@Controller

public class UserController {

4.1.2 @RequestMapping

      配置Controller的访问路径

1 在类上和方法名上配置

@Controller

@RequestMapping("UserController.do")

public class UserController {

@RequestMapping

public String register(){

return "index.jsp";

}

 

}

 这个Controller的访问路径为 UserController.do

 如何访问register方法?   

     如果UserController只有这个一个方法,那么访问这个Controller时,直接调用的就是这个方法。

其他配置:

@RequestMapping(method=RequestMethod.GET,params="method=reg")

配置说明:

     method=RequestMethod.GET 表示这个方法只有get请求时可以访问

     params="method=reg": Controller中有多个方法时,指定方法的访问方式。

Register方法的访问方式为:

     UserController.do?method=reg

2 只在方法名上配置(类上不添加@RequestMapping注解)

@RequestMapping("/reg")

public String register(){

return "index.jsp";

}

  这个方法的访问路径为: reg.do

  这样做的问题是: 当多个Controller中的方法上有相同的@RequestMapping配置时,无法区分。

   因此:只在方法上配置时,建议添加一个前缀

@RequestMapping("/UserController/reg")

public String register(){

return "index.jsp";

}

   方法的访问路径为: UserController/reg.do

4.2 获取客户端提交的数据

4.2.1使用方法参数HttpServletRequest

  public String register(HttpServletRequest request){

           String name = request.getParameter(“name”);

    return "index.jsp";

}

 

4.2.2 使用@RequestParam("")注解

public String register(@RequestParam("name") String name,@RequestParam("age") int age){}

@RequestParam("name") 注解中的参数要求和请求参数的key值相同

 

注意:当方法的参数名和请求key值相同时,@RequestParam注解可以省略

    

4.2.3 @PathVariable 注解

@RequestMapping(value="/hello/{name}/{age}")

public String hello(@PathVariable("name") String name,@PathVariable("age") int age){

//省略了 class 上的@RequestMapping

// 访问这个方法??? hello/zhangsan/100.do

System.out.println(name+"\t"+age);

return "/helloworld.jsp";

}

 

4.2.4 @ModelAttribute 注解

public String register(@ModelAttribute User user,@RequestParam("birthday111") String birthday)

 

客户端提交的数据会直接封装 user中,要保证请求参数的keyuser的属性相同

 

还会将user存入request作用域

对于Datebirthday无法完成直接的赋值,因此单独进行配置

 

4.2.5 解决日期类型赋值问题

      方式一:在Controller中添加如下代码

 @InitBinder

 public void initBinder(WebDataBinder binder) {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); // true:允许输入空值,false:不能为空值

 

    }

      方式二:编写、配置转换器

转换器:

public class DateConverter implements Converter<String, Date> {

 

@Override

public Date convert(String source) {

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

dateFormat.setLenient(false);

try {

return dateFormat.parse(source);

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

 

配置、引用

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

            <!-- 设置多个转换器 -->

            <property name="converters">

                <list>

                    <bean class="com.zrgk.converter.DateConverter"></bean>

                </list>

            </property>

</bean>

 

<mvc:annotation-driven conversion-service="conversionService" />

 

使用这种方式开启springMVC的注解方式,可以引入上面的转换器

 

    

4.3 使用作用域保存值

4.3.1 使用request.setAttribute()

4.3.2 通过方法的参数 ModelMap model

public String register(ModelMap modelMap){

 

             modelMap.put(“key”,Object);//放在request作用域

}

4.4 controller中使用Session

4.4.1 使用request获取

4.4.2 使用@SessionAttributes注解

@SessionAttributes({"user","name"})                  

public class RegisterController{

@RequestMapping(value="RegisterController/reg")

      public String register(ModelMap modelMap){

 

             modelMap.put("user",user); --放在request作用域

             modelMap.put("name","中软高科");

       }

   }

 

    modelMap中存的值 将会在session中也保存一份

 

4.5 关于跳转

4.5.1 转发

        方法返回字符串  默认是转发方式

4.5.2 重定向

return “redirect:index.jsp”

4.5.3 跳转路径 前缀后缀的设置

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"  

        p:prefix="/WEB-INF/view/" p:suffix=".jsp">  

        <property name="viewClass">             

            <value>org.springframework.web.servlet.view.JstlView</value>              

        </property>  

</bean>

 

return “index” 将会跳转到 /WEB-INF/view/index.jsp  

 

 

4.6 ModelAndView使用

public ModelAndView test2(){

 

    String name = “中软高科”;

    return new ModelAndView(new Redirect(“index.jsp”));

    

}

return new ModelAndView(new Redirect(“index.jsp”),”name”,name); -- 另一种带值得方式

 

return new ModelAndView(new RedirectViews(“index.jsp”),map); --map Map 也是用来带值

 

 

}

 

 

 

public ModelAndView test2(){

 

       ModelAndView mav = new ModelAndView();

 

       mav.setViewName(viewName); //设置跳转路径

       mav.addObject(obj) // 这种设置方式,带的值 key为这个对象所属类的 类名首字母小写

       mav.addObject(“key”,obj)

 

       return mav;

 

}

 

4.7 @ModelAttribute注解

4.7.1 获取客户端提交数据

public String register(@ModelAttribute User user,@RequestParam("birthday111") String birthday)

 

客户端提交的数据会直接封装 user中,要保证请求参数的keyuser的属性相同

 

还会将user存入request作用域

对于Datebirthday无法完成直接的赋值,因此单独进行配置

 

4.7.2 设置前置执行方法

加在方法上,方法将会在controller中要调用的方法之前执行

@ModelAttribute("myList")

public List<User> getList(){  //这个方法将在Controller中要调用的方法之前执行

System.out.println("getList......");

User u1 = new User(1,"aaa",20,new Date());

User u2 = new User(2,"bbb",30,new Date());

User u3 = new User(3,"ccc",40,new Date());

 

List<User> list = new ArrayList<User>();

list.add(u1);

list.add(u2);

list.add(u3);

 

return list;

}

 

页面可以直接根据 myList使用 方法返回的list使用C标签遍历即可。

5 声明式异常处理

  @ExceptionHandler({Exception.class})//异常处理

public String exceptionHandler(Exception e){

 

System.out.println(e.getMessage());

 

return "exception.jsp";

}

 

6 文件上传

6.1 依赖jar包

commons-fileUpload.jar

commons-io.jars

6.2 配置解析器

<bean id="multipartResolver"       

          class="org.springframework.web.multipart.commons.CommonsMultipartResolver"       

          p:defaultEncoding="utf-8">

</bean>

 

6.3 单个文件上传代码实现

@RequestMapping

  public String upload(HttpServletRequest request) throws

  Exception{

  

  MultipartHttpServletRequest req = (MultipartHttpServletRequest)request;

  

  MultipartFile mf = req.getFile("myFile");

  

  System.out.println(mf.getName());

  System.out.println(mf.getOriginalFilename());

  System.out.println(mf.getSize());

  

  InputStream is = mf.getInputStream();

  

  String folderPath =

  request.getSession().getServletContext().getRealPath("/upload");  

  OutputStream os = new

  FileOutputStream(folderPath+"/"+mf.getOriginalFilename());

  

  int len=0; byte[] b = new byte[1024];

 

  while((len=is.read(b))>0){

 

  os.write(b, 0, len); }

  

  is.close();

      os.close();

  

  return "success.jsp";

 }

 

6.4 文件上传代码实现

  public String upload(HttpServletRequest request,ModelMap model) throws Exception{

MultipartHttpServletRequest req = (MultipartHttpServletRequest)request;

List<MultipartFile> list  = req.getFiles("myFile");

String folderPath = request.getSession().getServletContext().getRealPath("/upload");

for(MultipartFile mf:list){

if(!mf.isEmpty()){

OutputStream os = new FileOutputStream(folderPath+"/"+mf.getOriginalFilename());

InputStream is = mf.getInputStream();

byte[] b = new byte[1024];

int len = 0;

while((len=is.read(b))>0){

os.write(b, 0, len);

}

is.close();

os.close();

System.out.println(mf.getName());

System.out.println(mf.getOriginalFilename());

}

}

return "success.jsp";

}

 

 

6.5 上传文件大小验证

<bean id="multipartResolver"           class="org.springframework.web.multipart.commons.CommonsMultipartResolver"       

          p:defaultEncoding="utf-8">

       <property name="maxUploadSize">

        <value>200000000000</value>

       </property>       

   </bean>  

          

  SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException  

该异常是SpringMVC在检查上传的文件信息时抛出来的,而此时还没有进入到Controller方法中 

因此,不能依靠Controller中的异常处理方式,需要在配置文件中进行配置

    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  

        <property name="exceptionMappings">  

            <props>  

                <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->  

                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload.jsp</prop>  

            </props>  

        </property>  

</bean>

 

 

 

 

 

 

7 拦截器(自定义拦截器)

7.1 实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,

Object arg2) throws Exception {

//Object arg2 指的是下一个拦截器对象

System.out.println("Controller之前执行...");

return true;

}

@Override

public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,

Object arg2, ModelAndView arg3) throws Exception {

System.out.println("controller之后,生成视图之前执行");

}

@Override

public void afterCompletion(HttpServletRequest arg0,

HttpServletResponse arg1, Object arg2, Exception arg3)

throws Exception {

System.out.println("最后执行,一般用来释放资源");

}

}

7.2 继承 HandlerInterceptorAdapter

可以指定覆盖哪个方法

 

7.3 配置拦截器

拦截器定义完成后,需要在配置文件中进行配置

<mvc:interceptors>  

    <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->  

         <bean class="web.interceptor.MyInterceptor"/>  

        <mvc:interceptor>  

             <mvc:mapping path="/RegisterController.do"/>  

                <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->  

                <bean class="web.interceptor.MyInterceptor2"/>  

         </mvc:interceptor>  

 </mvc:interceptors>

 

 

8 Controller方法返回JSON数据

8.1 添加jar包支持

jackson-core-asl.jar

     jackson-mapper-asl.jar

8.2 修改配置文件

<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射    --> 

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

       <property name="messageConverters">

            <list>

                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

                    <property name="supportedMediaTypes">

                        <list>

                            <value>text/html; charset=UTF-8</value>

                            <value>application/json;charset=UTF-8</value>

                        </list>

                    </property>

                </bean>

            </list>

        </property>

</bean>

 

 

 

8.3 Controller中方法

@RequestMapping

public @ResponseBody List<User> test(String name){

System.out.println(name+"-------------");

 

User u1 = new User("aaa","123",20);

User u2 = new User("bbb","345",21);

User u3 = new User("ccc","234",22);

 

List<User> list = new ArrayList<User>();

 

list.add(u1);list.add(u2);list.add(u3);

 

return list;

}

 

 

posted on 2018-09-09 18:03  云作  阅读(122)  评论(0)    收藏  举报

导航