spring-MVC

Spring MVC-Hello Spring MVC

web.xml

在WEB-INF目录下创建 web.xml

配置Spring MVC的入口 DispatcherServlet,把所有的请求都提交到该Servlet


<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <servlet>
        <servlet-name>springmvcservlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        servlet-class>
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>springmvcservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
web-app>

创建springmvc-servlet.xml

springmvc对应
这是Spring MVC的 映射配置文件

表示访问路径/index会交给id=indexController的bean处理

id=indexController的bean配置为类:IndexController



<beans>
    <bean id="simpleUrlHandlerMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/index">indexControllerprop>
            props>
        property>
    bean>
    <bean id="indexController" class="controller.IndexController">bean>
beans>

控制类 IndexController.java

控制类 IndexController实现接口Controller ,提供方法handleRequest处理请求

SpringMVC通过 ModelAndView 对象把模型和视图结合在一起

表示视图是index.jsp
模型数据是 message,内容是 “Hello Spring MVC”

public class IndexController implements Controller {
     
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
     
        ModelAndView mav = new ModelAndView("index.jsp");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

index.jsp

在WebContent目录下创建index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<h1>${
     message}</h1>

部署在tomcat中,重启测试

http://127.0.0.1:8080/springmvc/index

得到

Hello Spring MVC

原理

步骤 10 : 原理图 顶 折

  1. 用户访问 /index
  2. 根据web.xml中的配置 所有的访问都会经过DispatcherServlet
  3. 根据配置文件springmvc-servlet.xml ,访问路径/index
    会进入IndexController类
  4. 在IndexController中指定跳转到页面index.jsp,并传递message数据
  5. 在index.jsp中显示message信息
    spring-MVC_第1张图片

Spring MVC-视图定位

如果代码写成这样,就表示跳转到页面 index.jsp
new ModelAndView(“index.jsp”);

所谓的视图定位,指的是代码还是写成这样,但是会跳转到 /WEB-INF/page/index.jsp
new ModelAndView(“index”);

效果

虽然效果和在Hello Spring MVC中的效果是一样的,但是视图的配置方式发生了变化

Hello Spring MVC

修改springmvc-servlet.xml

增加

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

其作用是把视图约定在 /WEB-INF/page/*.jsp 这个位置

修改IndexController.java

把IndexController类的这一行代码

ModelAndView mav = new ModelAndView(“index.jsp”);
修改为
ModelAndView mav = new ModelAndView(“index”);

public class IndexController implements Controller {
     
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
     
    //ModelAndView mav = new ModelAndView("index.jsp");
        ModelAndView mav = new ModelAndView("index");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

移动index.jsp

在WEB-INF下新建目录page
把index.jsp移动到 WEB-INF/page 目录下

测试

访问页面

http://127.0.0.1:8080/springmvc/index
Hello Spring MVC

Spring MVC-注解方式

本例讲解如何使用注解的方式进行跳转的配置

效果

虽然效果和Hello Spring MVC中的一样,但是开发过程已经换成了注解方式

Hello Spring MVC

修改IndexController.java

在类前面加上@Controller 表示该类是一个控制器
在方法handleRequest 前面加上 @RequestMapping("/index") 表示路径/index会映射到该方法上
注意:不再让IndexController实现Controller接口

@Controller
public class IndexController {
     
    @RequestMapping("/index")
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
     
        ModelAndView mav = new ModelAndView("index");
        mav.addObject("message", "Hello Spring MVC");
        return mav;
    }
}

修改springmvc-servlet.xml

去掉映射相关的配置,因为已经使用注解方式了

增加

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

表示从包controller下扫描有@Controller注解的类

  <context:component-scan base-package="controller" />
    <bean id="irViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/" />
        <property name="suffix" value=".jsp" />
    bean>









beans>

测试

打开页面

http://127.0.0.1:8080/springmvc/index
Hello Spring MVC

看到的效果和通过配置是一样的

把/hello 跳转到 /hello.jsp 的配置,改为注解来实现

Spring MVC-接受表单数据

实体类Product.java

package pojo;
 
public class Product {
     
 
    private int id;
    private String name;
    private float 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 float getPrice() {
     
        return price;
    }
    public void setPrice(float price) {
     
        this.price = price;
    }
     
}

addProduct.jsp

在web目录下 (不是在WEB-INF下)增加商品的页面addProduct.jsp
注意:产品名称input的name要使用name,而不是 product.name

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
 
<form action="addProduct">
 
    产品名称 :<input type="text" name="name" value=""><br />
    产品价格: <input type="text" name="price" value=""><br />
 
    <input type="submit" value="增加商品">
form>

控制类ProductController.java

控制器ProductController,准备一个add方法映射/addProduct路径

为add方法准备一个Product 参数,用于接收注入

最后跳转到showProduct页面显示用户提交的数据

注: addProduct.jsp 提交的name和price会自动注入到参数 product里
注: 参数product会默认被当做值加入到ModelAndView 中,相当于:

 
mav.addObject("product",product);
 
@Controller
public class ProductController {
     
 
    @RequestMapping("/addProduct")
    public ModelAndView add(Product product) throws Exception {
     
        ModelAndView mav = new ModelAndView("showProduct");
        return mav;
    }
}

showProduct.jsp

在WEB-INF/page 目录下创建 showProduct.jsp
用 EL 表达式显示用户提交的名称和价格

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
产品名称: ${product.name}<br>
产品价格: ${product.price}

测试

步骤 8 : 测试
访问页面

http://127.0.0.1:8080/springmvc/addProduct.jsp
 

提交数据,显示结果

产品名称:product
产品价格:100.0

Spring MVC-客户端跳转

在前面的例子中,无论是/index跳转到index.jsp 还是/addProduct 跳转到showProduct.jsp,都是服务端跳转。

本例讲解如何进行客户端跳转

效果

访问页面

http://127.0.0.1:8080/springmvc/jump
结果客户端跳转到了
127.0.0.1:8080/springmvc/index

Hello Spring MVC

修改IndexController.java

首先映射/jump到jump()方法
在jump()中编写如下代码

ModelAndView mav = new ModelAndView(“redirect:/index”);

redirect:/index
即表示客户端跳转的意思

增加

@RequestMapping("/jump")
    public ModelAndView jump() {
     
        ModelAndView mav = new ModelAndView("redirect:/index");
        return mav;
    }  

通过访问路径/hello 跳转到/index

Spring MVC- SESSION

Session在用户登录,一些特殊场合在页面间传递数据的时候会经常用到

效果

访问路径/check,可以不停刷新session中记录的访问次数

修改IndexController.java

映射 /check 到方法check()
为方法check()提供参数HttpSession session,这样就可以在方法体中使用session了
接下来的逻辑就是每次访问为session中的count+1.
最后跳转到check.jsp页面

@RequestMapping("/check")
    public ModelAndView check(HttpSession session) {
     
        Integer i = (Integer) session.getAttribute("count");
        if (i == null)
            i = 0;
        i++;
        session.setAttribute("count", i);
        ModelAndView mav = new ModelAndView("check");
        return mav;
    }

check.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
session中记录的访问次数:${count}

测试

访问页面

http://127.0.0.1:8080/springmvc/check

每次访问,次数都+1

Spring MVC- 中文问题

在Spring MVC中处理中文问题和Filter处理中文问题是一样的手段

效果

访问地址提交中文

http://127.0.0.1:8080/springmvc/addProduct.jsp

产品名称:中文
产品价格:123.0

修改web.xml

增加


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

addProduct.jsp

为form 设置method=“post”

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
 
<form action="addProduct" method="post">
 
    产品名称 :<input type="text" name="name" value=""><br />
    产品价格: <input type="text" name="price" value=""><br />
 
    <input type="submit" value="增加商品">
</form>

Spring MVC- 上传文件

效果

访问地址:

http://127.0.0.1:8080/springmvc/upload.jsp

这个通过springmvc上传图片,并显示的效果
spring-MVC_第2张图片

配置web.xml允许访问*.jpg

在web.xml中新增加一段


	<servlet-mapping>
	    <servlet-name>defaultservlet-name>
	    <url-pattern>*.jpgurl-pattern>
	servlet-mapping>

表示允许访问*.jpg。

为什么要加这一段呢? 因为配置springmvc的servlet的时候,使用的路径是"/",导致静态资源在默认情况下不能访问,所以要加上这一段,允许访问jpg。 并且必须加在springmvc的servlet之前

配置springmvc-servlet.xml

新增加一段配置

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

upload.jsp 上传页面

上传页面,需要注意的是form 的两个属性必须提供
method=“post” 和 enctype=“multipart/form-data” 缺一不可
上传组件 增加一个属性 accept=“image/*” 表示只能选择图片进行上传
留意 这个image,后面会用到这个image

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
  
<form action="uploadImage" method="post" enctype="multipart/form-data">
  选择图片:<input type="file" name="image" accept="image/*" /> <br>
  <input type="submit" value="上传">
</form>

准备UploadedImageFile.java

在UploadedImageFile中封装MultipartFile类型的字段 image ,用于接受页面的注入

这里的字段 image必须和上传页面upload.jsp中的image

保持一致

package pojo;
 
import org.springframework.web.multipart.MultipartFile;
 
public class UploadedImageFile {
     
    MultipartFile image;
 
    public MultipartFile getImage() {
     
        return image;
    }
 
    public void setImage(MultipartFile image) {
     
        this.image = image;
    }
 
}

UploadController.java 上传控制器

新建类UploadController 作为上传控制器
准备方法upload 映射上传路径/uploadImage

  1. 方法的第二个参数UploadedImageFile 中已经注入好了 image
  2. 通过 RandomStringUtils.randomAlphanumeric(10);获取一个随机文件名。 因为用户可能上传相同文件名的文件,为了不覆盖原来的文件,通过随机文件名的办法来规避
  3. 根据request.getServletContext().getRealPath 获取到web目录下的image目录,用于存放上传后的文件。
  4. 调用file.getImage().transferTo(newFile); 复制文件
  5. 把生成的随机文件名提交给视图,用于后续的显示
@Controller
public class UploadController {
     
 
    @RequestMapping("/uploadImage")
    public ModelAndView upload(HttpServletRequest request, UploadedImageFile file)
            throws IllegalStateException, IOException {
     
        String name = RandomStringUtils.randomAlphanumeric(10);
        String newFileName = name + ".jpg";
        File newFile = new File(request.getServletContext().getRealPath("/image"), newFileName);
        newFile.getParentFile().mkdirs();
        file.getImage().transferTo(newFile);
 
        ModelAndView mav = new ModelAndView("showUploadedFile");
        mav.addObject("imageName", newFileName);
        return mav;
    }
}

showUploadedFile.jsp 显示图片的页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<img src="image/${imageName}"/>

Spring MVC- 拦截器

效果

步骤 4 : 效果
访问地址之后,看到如图所示的拦截器打印的效果

http://127.0.0.1:8080/springmvc/index
spring-MVC_第3张图片

拦截器类:IndexInterceptor.java

public class IndexInterceptor extends HandlerInterceptorAdapter {
      
 
     /** 
     * 在业务处理器处理请求之前被调用 
     * 如果返回false 
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * 如果返回true 
     *    执行下一个拦截器,直到所有的拦截器都执行完毕 
     *    再执行被拦截的Controller 
     *    然后进入拦截器链, 
     *    从最后一个拦截器往回执行所有的postHandle() 
     *    接着再从最后一个拦截器往回执行所有的afterCompletion() 
     */   
    public boolean preHandle(HttpServletRequest request,   
            HttpServletResponse response, Object handler) throws Exception {
     
         
        System.out.println("preHandle(), 在访问Controller之前被调用"); 
        return true;
         
    } 
 
    /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作   
     * 可在modelAndView中加入数据,比如当前时间
     */ 
     
    public void postHandle(HttpServletRequest request,   
            HttpServletResponse response, Object handler,   
            ModelAndView modelAndView) throws Exception {
      
        System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
        modelAndView.addObject("date","由拦截器生成的时间:" + new Date());
    } 
 
    /** 
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等  
     *  
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion() 
     */
     
    public void afterCompletion(HttpServletRequest request,   
            HttpServletResponse response, Object handler, Exception ex) 
    throws Exception {
      
           
        System.out.println("afterCompletion(), 在访问视图之后被调用"); 
    } 
       
}

修改springmvc-servlet.xml以对/index路径进行拦截

增加

<mvc:interceptors>   
        <mvc:interceptor>   
            <mvc:mapping path="/index"/> 
             
            <bean class="interceptor.IndexInterceptor"/>     
        mvc:interceptor> 
         
    mvc:interceptors>

修改 index.jsp

打印拦截器放进去的日期

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<h1>${message}</h1>
 
<p>${date}</p>

本文章代码

https://how2j.cn/k/springmvc/springmvc-springmvc/615.html

你可能感兴趣的:(javaee企业级)