SpringMVC1

一.建立SpringMVC步骤

1.配置Maven的依赖或导jar包
2.在 web.xml 中配置 DispatcherServlet并加入 Spring MVC 的配置文件
 <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
3.编写处理请求的处理器,并标识为处理器
 <!--配置自动扫描-->
    <context:component-scan base-package="com.itlc.springmvc"/>
4.编写视图

    <!--配置视图解析器:如何把handler方法返回值解析为实际的物理视图-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

二.使用 @RequestMapping 映射请求

1.类加入容器,加@Controller
2.@RequestMapping作用点

– 类定义处:提供初步的请求映射信息。相对于 WEB 应用的根目录
– 方法处:提供进一步的细分映射信息。相对于类定义处的 URL。若
类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于
WEB 应用的根目录

@RequestMapping("/testMethod")
    public String testMethod(){
        System.out.println("testMethod");
        return SUCCESS;
    }

3. @RequestMapping 修饰其他的

除了可以使用请求 URL 映射请求外,
还可以使用请求方法、请求参数及请求头映射请求
@RequestMapping 的 value、method、params 及 heads
分别表示请求 URL、请求方法、请求参数及请求头的映射条
件,他们之间是与的关系,联合使用多个条件可让请求映射
更加精确化。
params 和 headers支持简单的表达式:
– param1: 表示请求必须包含名为 param1 的请求参数
– !param1: 表示请求不能包含名为 param1 的请求参数
– param1 != value1: 表示请求包含名为 param1 的请求参数,但其值
不能为 value1
– {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2
的两个请求参数,且 param1 参数的值必须为 value1

    Ant 风格资源地址支持 3 种匹配符:
    ?:匹配文件名中的一个字符
    *:匹配文件名中的任意字符
    **:** 匹配多层路径
@RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        System.out.println("testRequestMapping");
        return SUCCESS;
    }

    /*
        @PathVariable 可以用来映射URL中的占位符到目标方法的参数中
        @param id
    */
    @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable("id") Integer id){
        System.out.println("testPathVariable: "+id);
        return SUCCESS;
    }
4.REST

– /order/1 HTTP GET :得到 id = 1 的 order
– /order/1 HTTP DELETE:删除 id = 1的 order
– /order/1 HTTP PUT:更新id = 1的 order
– /order HTTP POST:新增 order
HiddenHttpMethodFilter:浏览器 form 表单只支持 GET
与 POST 请求,而DELETE、PUT 等 method 并不支
持,Spring3.0 添加了一个过滤器,可以将这些请求转换
为标准的 http 方法,使得支持 GET、POST、PUT 与
DELETE 请求

过滤器:

<!--配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求
  转化为DELETE或POST请求-->
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

处理器:

@RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
    public String testRestPut(@PathVariable Integer id) {
        System.out.println("testRest Put: " + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
    public String testRestDelete(@PathVariable Integer id) {
        System.out.println("testRest Delete: " + id);
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest", method = RequestMethod.POST)
    public String testRest() {
        System.out.println("testRest POST");
        return SUCCESS;
    }

    @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
    public String testRest(@PathVariable Integer id) {
        System.out.println("testRest GET: " + id);
        return SUCCESS;
    }

三.映射请求参数 & 请求参数

Spring MVC 通过分析处理方法的签名,将 HTTP 请求信
息绑定到处理方法的相应人参中。
• Spring MVC 对控制器处理方法签名的限制是很宽松的,
几乎可以按喜欢的任何方式对方法进行签名。
• 必要时可以对方法及方法入参标注相应的注解(
@PathVariable
、@RequestParam、@RequestHeader 等)、Spring
MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参
中,并根据方法的返回值类型做出相应的后续处理。

1.@RequestParam

@RequestParam来映射请求参数,处理表单value 值即请求参数的参数名
,required表示该参数是否必须,默认为truedefaultValue请求参数的默认值

public String testRequestParam(@RequestParam(value = "username") String un,
                                   @RequestParam(value = "age",required = false,defaultValue = "0") int age){
        System.out.println("testRequestParam,username"+un+",age:"+age);
        return SUCCESS;
    }
2.@RequestHeader(了解)

@RequestHeader来映射请求消息头
用法同@RequestParam

 @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al){
        System.out.println("testRequestHeader:Accept-Language"+al);
        return SUCCESS;
    }
3.@CookieValue(了解)

@CookieValue来映射cookie
用法同@RequestParam

@RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String js){
        System.out.println("testCookieValue: sessionId:"+js);
        return SUCCESS;
    }
4.pojo

表格提交利用类结合表单,直接得到对象,允许多级联动

@RequestMapping("/testPojo")
    public String testPojo(User user){
        System.out.println("testPojo:"+user);
        return SUCCESS;
    }

表单:
<form action="springmvc/testPojo" method="POST">
    用户名:<input type="text" name="userName"/><br/>
    密码:<input type="password" name="password"/><br/>
    邮箱:<input type="text" name="email"/><br/>
    年龄:<input type="text" name="age"/><br/>
    省份  <input type="text" name="address.province"/><br/>
    城市:<input type="text" name="address.city"/><br/>
    <input type="submit" value="Submit"/><br/>
</form>

User类:
package com.itlc.springmvc.entities;

public class User {
    private int id;
    private String userName;
    private String passWord;
    private String email;
    private int age;
    private Address address;

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", userName='" + userName + '\'' + ", passWord='" + passWord + '\'' + ", email='" + email + '\'' + ", age=" + age + ", address=" + address + '}';
    }

    public User(){}

    public String getUserName() {
        return userName;
    }

    public User setUserName(String userName) {
        this.userName = userName;
        return this;
    }

    public String getPassWord() {
        return passWord;
    }

    public User setPassWord(String passWord) {
        this.passWord = passWord;
        return this;
    }

    public String getEmail() {
        return email;
    }

    public User setEmail(String email) {
        this.email = email;
        return this;
    }

    public int getAge() {
        return age;
    }

    public User setAge(int age) {
        this.age = age;
        return this;
    }

    public Address getAddress() {
        return address;
    }

    public User(int id, String userName, String passWord, String email, int age, Address address) {
        this.id = id;
        this.userName = userName;
        this.passWord = passWord;
        this.email = email;
        this.age = age;
        this.address = address;
    }

    public int getId() {

        return id;
    }

    public User setId(int id) {
        this.id = id;
        return this;
    }

    public User setAddress(Address address) {
        this.address = address;
        return this;
    }
}
5.API作为目标参数

可以使用Servlet原生的API作为目标参数,可以支持以下的 ServletAPI 类型的参数
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer

 @RequestMapping("/testServletAPI")
    public String testServletAPI(HttpServletRequest request, HttpServletResponse response){
        System.out.println("testServletAPI,"+request+","+response);
        return SUCCESS;
    }

四.处理模型数据

Spring MVC 提供了以下几种途径输出模型数据:
– ModelAndView: 处理方法返回值类型为 ModelAndView
时, 方法体即可通过该对象添加模型数据
– Map 及 Model: 入参为
org.springframework.ui.Model、org.springframework.ui.
ModelMap 或 java.uti.Map 时,处理方法返回时,Map
中的数据会自动添加到模型中。
– @SessionAttributes: 将模型中的某个属性暂存到
HttpSession 中,以便多个请求之间可以共享这个属性
– @ModelAttribute: 方法入参标注该注解后, 入参的对象
就会放到数据模型中

1. ModelAndView

目标方法的返回值可以是ModelAndView类型
其中包括视图和模型信息
springMVC会把ModelAndView的model中数据放入到request对象中

 @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        String viewName=SUCCESS;
        ModelAndView modelAndView=new ModelAndView(viewName);

        //添加模型数据到ModelAndview
        modelAndView.addObject("time",new Date());
        return modelAndView;
    }
2. Map类型

目标方法可以添加Map类型(也可以是Model或者ModelMap类型)的参数

@RequestMapping("/testMap")
    public String testMap(Map<String,Object> map){
        map.put("names", Arrays.asList("Tom","Jerry","Mike"));
        return SUCCESS;
    }
3.SessionAttributes

@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(使用value属性值),
还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(使用type属性值)

注意:该注解只能放在类的上面,不能放在方法上边
4.@ModelAttribute

当有@ModelAttribute标记的方法时的执行步骤:
1.执行有@ModelAttribute注解标记的方法:从数据库中取出对象,把对象放到Map中,键为user
2.springMVC从Map中取出User对象,并把表单中的请求参数赋给User对象的对应属性
3.springMVC把上述对象传入目标方法的参数

        注意:在@ModelAttribute注解标记的方法中,放入Map时的键需要和目标方法参数类型的第一个
        字母小写的字符串一致

        SpringMVC确定目标方法POJO类型入参的过程
        1.确定一个key:
            若目标方法的POJO属性使用了@ModelAttribute来修饰,则attrName值即为
            @ModelAttribute的value属性值

        2.在implicitModel中查找key对应的对象,若存在,则作为入参传入
            若在@ModelAttribute标记的方法中在Map中保存过,且key和确定key一致,则会获取到

        3.若implicitModel中不存在key对应的对象,则检查当前的Handler是否使用@SessionAttributes注解修饰,
        若使用了该注解,且@SessionAttributes注解的value属性值包含了key,则会从HttpSession中获取key所对
        应的value值,若存在则直接传入到目标方法的入参中,若不存在则将抛出异常
        4.若Handler没有标识@SessionAttributes注解或者@SessionAttributes注解的value值不包含key,则会通
        过反射来创建POJO类型的参数,传入为目标方法的参数
        5.SpringMVC会把key和POJO对象保存到implicitModel中,进而会保存到request中

        源码分析流程
            1.调用@ModelAttribute标记的方法,实际上把@ModelAttribute标记的方法中的Map中的数据
            放在了limplicitModel中。
            2.解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder对象的target属性
                (1)创建WebDataBinder对象:
                    1)确定objectName属性:若传入的attrName属性值为""。则objectName为类名第一个字母小写
                    注意:attrName,若目标方法的POJO属性使用了@ModelAttribute来修饰,则attrName值即
                    为@ModelAttribute的value属性值
                (2)确定target属性:
                    >在implicitModel中查找attrName对应的属性值,若存在,ok
                    >*若不存在:则验证当前的Handler中是否使用了@SessionAttributes进行修饰,若使用了,
                    则尝试从Session中获取对应的attrName所对应的属性值。若session中没有对应的属性值
                    则抛出了异常
                    >若Handler没有使用@SessionAttributes进行修饰,或@SessionAttributes中没有使用
                    value值指定的key和attrName相匹配,则通过反射创建了POJO对象
            3.SpringMVC把表单中的请求参数赋给了WebDataBinder的target对应的属性
            4.*SpringMVC会把WebDataBinder的attrName和target给到limplicitModel,进而传到request域中
            5.把WebDataBinder的target作为参数传递给目标方法的入参
@RequestMapping("/testModelAttribute")
    public String testModelAttribute(@ModelAttribute(value = "kk") User user){
        System.out.println("修改:"+user);
        return SUCCESS;
    }

1.有@ModelAttribute标记的方法,会在每个目标方法执行之前被springMVC调用
2.@ModelAttribute注解也可以来修饰目标方法POJO类型的入参,其value属性值有如下的作用:
(1)SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接
传入到目标方法入参中
(2)SpringMVC会以value为key,POJO类型的对象为value,存入到request中

  @ModelAttribute
    public void getUser(@RequestParam(value = "id",required = false) Integer id,Map<String,Object> map){
        if (id!=null){
            /*模拟获得*/
            User user=new User(1,"tom","123456","[email protected]",12,new Address("1","2"));
            System.out.println("从数据库获得一个对象"+user);

            map.put("kk",user);
        }
    }

五.视图和视图解析器

请求处理方法执行完成后,最终返回一个 ModelAndView
对象。对于那些返回 String,View 或 ModeMap 等类型的
处理方法,Spring MVC 也会在内部将它们装配成一个
ModelAndView 对象,它包含了逻辑名和模型对象的视图
• Spring MVC 借助视图解析器(ViewResolver)得到最终
的视图对象(View),最终的视图可以是 JSP ,也可能是
Excel、JFreeChart 等各种表现形式的视图

1.配置国际化资源文件
<!--配置国际化资源文件-->
    <bean id="MessageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n"/>
    </bean>
2.自定义视图
<!--配置自定义视图BeanNameViewResolver解析器:使用视图的名字来解析视图-->
    <!--通过order属性来定义视图解析器的优先级,order值越小优先级越高-->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <property name="order" value="100"/>
    </bean>

自定义视图类实现View接口并添加@Component标签,放入容器中

@Component
public class HelloView implements View{
    @Override
    public String getContentType() {
        return "text/html";
    }

    @Override
    public void render(Map<String, ?> map, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        httpServletResponse.getWriter().print("hello view,time:"+new Date());
    }
}

则调用该处理器时会调用自定义视图中的render方法

 @RequestMapping("/helloView")
    public String testView(){
        System.out.println("helloView");
        return "helloView";
    }
3.请求转发

请求转发和重定向,如果返回的字符串中带 forward: 或 redirect: 前缀
时,SpringMVC 会对他们进行特殊处理:将 forward: 和
redirect: 当成指示符,其后的字符串作为 URL 来处理
– redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
– forward:success.jsp:会完成一个到 success.jsp 的转发操作

@RequestMapping("/testRedirect")
    public String testRedirect(){
        System.out.println("testRedirect");
        return "redirect:/index.jsp";
    }

猜你喜欢

转载自blog.csdn.net/maniacxx/article/details/79671798