spring mvc总结

1、DispatcherServlet

  DispatcherServlet是SpringMVC的核心,它负责将请求路由到其他的组件之中。

  扩展AbstractAnnotationConfigDispatcherServletInitializer的任意类都会自动地配置DispatcherServlet和Spring应用上下文,Spring的应用上下文会位于应用程序的Servlet上下文之中。

  解析:在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,Spring提供了这个接口的实现SpringServletContainerInitializer,这个类再查找实现了WebApplicationInitializer的类,也就是AbstractAnnotationConfigDispatcherServletInitializer。

  当DispatcherServlet启动的时候,它会创建Spring应用上下文,并加载配置文件或者配置类中所声明的bean

2、@Controller注解:

  这个注解是用来声明控制器的,它基于@Component注解,它的目的就是辅助实现组件扫描,组件扫描器会自动找到带有@Controller注解的类,并将其声明为Spring应用上下文中的一个bean。

3、@RequestMapping注解:@RequestMapping(value="/",method=GET)

  它的value属性指定了这个方法索要处理的请求路径,method属性细化了它所处理的HTTP方法。

@Controller
@RequestMapping("/spittles")
public class SpittleController {
    //private static final String MAX_LONG_AS_STRING = Long.toString(Long.MAX_VALUE);
    private SpittleRepository spittleRepository;
    @Autowired
    public SpittleController(
        SpittleRepository spittleRepository){
        this.spittleRepository = spittleRepository;
    }
    /**
     * 我们在spittles()方法中给定了一个Model作为参数。
     * 这样, spittles()方法就能将Repository中获取到的Spittle列表填充到模型中。
     * Model实际上就是一个Map( 也就是key-value对的集合) , 
     * 它会传递给视图, 这样数据就能渲染到客户端了。 
     * 当调用addAttribute()方法并且不指定key的时候, 
     * 那么key会根据值的对象类型推断确定。 在本例中, 因为它是一个List<Spittle>,
     *  因此, 键将会推断为spittleList。
     * @param model
     * @return
     */
//    @RequestMapping(method=RequestMethod.GET)
//    public String spittles(Model model){
//        model.addAttribute(
//                spittleRepository.findSpittles(Long.MAX_VALUE, 20));
//        return "spittles";
//    }
    /**
     * 如果你希望显式声明模型的key的话, 那也尽可以进行指定。
     * 例如, 下面这个版本的spittles()方法与程序清单5.10中的方法作用是一样的:
     * @param model
     * @return
     */
//    @RequestMapping(method=RequestMethod.GET)
//    public String spittles(Model model){
//        model.addAttribute("spittleList",//第一个参数是String
//                spittleRepository.findSpittles(Long.MAX_VALUE, 20));
//        return "spittles";
//    }
    /**
     * 如果你希望使用非Spring类型的话, 那么可以用java.util.Map来代替Model。 
     * 下面这个版本的spittles()方法与之前的版本在功能上是一样的:
     * @return
     */
//    @SuppressWarnings("unchecked")
//    @RequestMapping(method=RequestMethod.GET)
//    public String spittles(Map model){
//        model.put("spittleList",//第一个参数是Object
//                spittleRepository.findSpittles(Long.MAX_VALUE, 20));
//        return "spittles";
//    }
    /**
     * 这个版本与其他的版本有些差别。 它并没有返回视图名称, 也没有显式地设定模型, 
     * 这个方法返回的是Spittle列表。 当处理器方法像这样返回对象或集合时, 
     * 这个值会放到模型中, 模型的key会根据其类型推断得出( 在本例中, 也就是spittleList) 。
     * 而逻辑视图的名称将会根据请求路径推断得出。 
     * 因为这个方法处理针对“/spittles”的GET请求,
     * 因此视图的名称将会是spittles( 去掉开头的斜线) 。
     * @return
     */
//    @RequestMapping(method=RequestMethod.GET)
//    public List<Spittle> spittles(){
//        return spittleRepository.findSpittles(Long.MAX_VALUE, 20);
//    }
    /////////////////////////////////////////////////////////////////
    /**
     * 不管你选择哪种方式来编写spittles()方法, 所达成的结果都是相同的。 
     * 模型中会存储一个Spittle列表, key为spittleList, 然后这个列表会发送到名为spittles的视图中。
     * 按照我们配置InternalResourceViewResolver的方式, 
     * 视图的JSP将会是“/WEBINF/views/spittles.jsp”。
     */
    /////////////////////////////////////////////////////////////////
    
    //////////////处理带参数的请求///////////////////
//    @RequestMapping(method=RequestMethod.GET)
//    public List<Spittle> spittles(
//            @RequestParam("max") long max,
//            @RequestParam("count") int count){
//        return spittleRepository.findSpittles(max, count);
//    }
    /**
     * SpittleController中的处理器方法要同时处理有参数和没有参数的场景, 
     * 那我们需要对其(上面方法)进行修改, 让它能接受参数, 同时, 如果这些参数在请求中不存在的话, 
     * 就使用默认值Long.MAX_VALUE和20。 
     * @RequestParam注解的defaultValue属性可以完成这项任务:
     * @param max
     * @param count
     * @return
     */
    private static final String MAX_LONG_AS_STRING =
            Long.toString(Long.MAX_VALUE);
    /**
     * 尽管defaultValue属性给定的是String类型的值,
     * 但是当绑定到方法的max参数时, 它会转换为Long类型。
     * 如果请求中没有count参数的话, count参数的默认值将会设置为20
     * @param max
     * @param count
     * @return
     * 这个测试没有成功!!!
     */
//    @RequestMapping(method=RequestMethod.GET)
//    public List<Spittle> spittles(
//            @RequestParam(value="max",
//                        defaultValue="238900") long max,
//            @RequestParam(value="count",defaultValue="20") int count){
//        return spittleRepository.findSpittles(max, count);
//    }
    
    
    /**
     * 通过路径参数接受输入
     * 假设我们的应用程序需要根据给定的ID来展现某一个Spittle记录。 
     * 其中一种方案就是编写处理器方法, 通过使用@RequestParam注解,
     * 让它接受ID作为查询参数:
     * @param spittleId
     * @param model
     * @return
     * 这个处理器方法将会处理形如“/spittles/show?spittle_id=12345”这样的请求。
     * 尽管这也可以正常工作, 但是从面向资源的角度来看这并不理想。
     * 在理想情况下, 要识别的资源( Spittle) 应该通过URL路径进行标示, 而不是通过查询参数。 
     * 对“/spittles/12345”发起GET请求要优于对“/spittles/show?spittle_id=12345”发起请求。 
     * 前者能够识别出要查询的资源, 而后者描述的是带有参数的一个操作——本质上是通过HTTP发起的RPC。 
     */
//    @RequestMapping(value="/show",method=RequestMethod.GET)
//    public String showSpittle(
//            @RequestParam("spittle_id")long spittleId,Model model){
//        model.addAttribute(spittleRepository.findOne(spittleId));
//        return "spittle";
//        
//    }
//    
    /**
     * 到目前为止, 在我们编写的控制器中, 所有的方法都映射到了( 通过@RequestMapping) 静态定义好的路径上。 
     * 但是, 如果想让这个测试通过的话, 我们编写的@RequestMapping要包含变量部分, 
     * 这部分代表了Spittle ID。
     * 为了实现这种路径变量, Spring MVC允许我们在@RequestMapping路径中添加占位符。 
     * 占位符的名称要用大括号( “{”和“}”) 括起来。 路径中的其他部分要与所处理的请求完全匹配, 
     * 但是占位符部分可以是任意的值。
     * @param spittleId
     * @param model
     * @return
     * 我们可以看到, spittle()方法的spittleId参数上添加了@PathVariable("spittleId")注解, 
     * 这表明在请求路径中, 不管占位符部分的值是什么都会传递到处理器方法的spittleId参数中。 
     * 如果对“/spittles/54321”发送GET请求, 那么将会把“54321”传递进来, 作为spittleId的值。
     */
//    @RequestMapping(value="/{spittleId}",method=RequestMethod.GET)
//    public String spittle(
//            @PathVariable("spittleId")long spittleId,
//            Model model){
//        model.addAttribute(spittleRepository.findOne(spittleId));
//        return "spittle";
//    }
    
    /**
     * 需要注意的是: 在样例中spittleId这个词出现了好几次: 
     * 先是在@RequestMapping的路径中, 然后作为@PathVariable属性的值,
     * 最后又作为方法的参数名称。 因为方法的参数名碰巧与占位符的名称相同,
     * 因此我们可以去掉@PathVariable中的value属性:
     * @param spittleId
     * @param model
     * @return
     * 如果@PathVariable中没有value属性的话, 它会假设占位符的名称与方法的参数名相同。
     * 这能够让代码稍微简洁一些, 因为不必重复写占位符的名称了。 
     * 但需要注意的是, 如果你想要重命名参数时, 必须要同时修改占位符的名称, 使其互相匹配。
     * 
     * spittle()方法会将参数传递到SpittleRepository的findOne()方法中,
     * 用来获取某个Spittle对象, 然后将Spittle对象添加到模型中。 
     * 模型的key将会是spittle, 这是根据传递到addAttribute()方法中的类型推断得到的。
     */
    @RequestMapping(value="/{spittleId}",method=RequestMethod.GET)
    public String spittle(
            @PathVariable long spittleId,
            Model model){
        model.addAttribute(spittleRepository.findOne(spittleId));
        return "spittle";
    }
}
View Code

 

posted @ 2017-08-15 15:15  小小小涛  阅读(109)  评论(0)    收藏  举报