个人读书笔记,题外话都写在第1章https://blog.csdn.net/u013652550/article/details/119800308。
第7章主要介绍了MVC框架。其中配置部分内容过多,后面即将学习的Spring Boot又很好地解决了这一问题,故略读。
7.1 MVC框架
MVC是模型(Model)—视图(View)—控制器(Controller)的缩写。
7.2 Spring MVC处理流程
引入依赖:
spring-core、spring-beans、spring-context、spring-jdbc、spring-expression、spring-web、spring-webmvc、spring-tx、(javax.servlet)jstl、(taglibs)standard、(javax.servlet)javax.servlet-api、(javax.servlet.jsp)jsp-api、(junit)junit等(括号内为groupId),以及插件maven-compiler-plugin。
配置spring-context:
在之前常用的配置基础上,beans元素加入xmlns:mvc、xmlns:tx、xmlns:util、xmlns:aop等即可。
配置spring-mvc.xml:
由于IDEA新建Spring Boot项目不需配置,掠过本部分。书上原码见P140~141,需要对org.springframework.http.converter.StringHttpMessageConverter、org.springframework.http.converter.ResourceHttpMessageConvert、org.springframework.web.servlet.view.InternalResourceViewResolver进行配置。
配置web.xml:
需要配置context-param、listener、servlet、servlet-mapping、filter等。可以使用注解,同上略过,有关详细内容以后用时再查询。书上代码见P141~142。注意更改项目结构:Spring Boot下使用JSP页面_kevin-CSDN博客
处理流程:
总结:请求→映射→返回→适配→处理→返回→返回→解析→返回→渲染→响应。
7.3 HandlerMapping的使用
编程时使用@RequestMapping注解即可,即RequestMappingHandlerMapping。还可以使用BeanNameUrlHandlerMapping,将url映射到对应的Controller。在spring-mvc.xml中配置bean示例:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="/hello.do" class="com.demo.Controller.HelloController"/>
亦可使用SimpleUrlHandlerMapping。有两种常见的映射方法。
一是通过prop key:
<bean id="helloController" class="com.demo.Controller.HelloController/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.html">helloController</prop>
</props>
</property>
</bean>
二是通过value:
<bean id="helloController" class="com.demo.Controller.HelloController"/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*/hello.html=helloController
</value>
</property>
</bean>
7.4 传递参数到Controller
1. URL传递数据到Controller
@RequestParam:常见的url为带?和&的url,该注解适用于类似于"name,pwd"的url。可选参数可设置required=false(默认true)。用于形参列表中。
@RequestMapping(value="/login.do")
public ModelAndView login(HttpServletRequest request, HttpServletResponse response, @RequestParam("name") String name, @RequestParam(value="pwd", required=false) String pwd) {...}
@PathVariable:适用于url/param1/param2格式的url。同样用于形参列表中。
@RequestMapping(value="/getlogin/{name}/{pwd}", method=RequestMethod.GET)
public ModelAndView getlogin(HttpServletRequest request, HttpServletResponse response, @PathVariable("name") String name, @PathVariable("pwd") String pwd) {...}
2. View传递数据到Controller
1. 可以直接将请求参数名作为Controller中方法的形参。
2. 当请求参数很多时,可以使用POJO对象(需事先设置setter和getter方法)。
3. 亦可使用原生的Servlet API作为Controller方法的参数(调用request.getParameter("xxx")即可)。
7.5 传递数据到View
ModelAndView
调用modelAndView.addObject(String name, Object obj)方法将model添加,然后返回即可。示例index.jsp的body体中使用EL表达式即可获取(如:${user.name},${user.pwd})。亦可设置方法参数为Model,在方法内将参数显式添加至Model,返回jsp页面名称。
@RequestMapping("/login.do")
public String login(Model model) {
User user = new User();
user.setUsername("admin");
user.setPassword("123456");
model.addAttribute("user", user);
return "index";
}
@SessionAttributes
用于暂存属性,以便于多个请求之间共享,例如用户登录信息。该注解只能放在类上。
@ModelAttribute
Spring MVC在每次调用请求处理方法时都会创建Model类型的一个实例。如果准备使用此实例,就可以在方法中添加一个Model类型的参数。可以使用@ModelAttribute来注释方法参数:带有@ModelAttribute注解的方法会讲其输入或创建的参数对象添加到Model对象中(若方法中没有显式添加)。也可用@ModelAttribute标注一个非请求的处理方法(有返回值,无返回值):被@ModelAttribute注释的方法会在此Controller每个方法执行前被执行。
@RequestMapping(value="...",method=RequestMethod.GET)
public String xxx(HttpServletRequest request, HttpServletResponse response, @ModelAttribute("user") User user, @ModelAttribute("name") String name, Model model) {...}
用于方法前的示例:
@ModelAttribute(value = "mymap")
public Map<String, Object> map() {
User user = new User();
user.setName("abc");
user.setPwd("123456");
HashMap<String, Object> map = new HashMap<>();
map.put("user", user);
return map;
}
在jsp页面中获取值就必须加上@ModelAttribute的value值。如${mymap.user.name},${mymap.user.pwd}。无返回值方法需要在方法体中显式调用model.addAttribute方法将参数添加至model中。
7.6 拦截器的使用
新建拦截器类,实现HandlerInterceptor接口中所需方法即可。
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
示例代码见P160。书中调用了request.getRequestDispatcher("...").forward(request, reponse)进行页面跳转。这里还有一种页面跳转方法redirect,区别在于前者是服务端行为,后者是客户端行为。
关于拦截器的配置,可以在sspring-mvc.xml中使用<mvc:interceptors>元素进行配置,亦可使用注解,实现WebMvcConfigurer接口中的addInterceptors方法即可。详见springboot下使用拦截器和过滤器_学习-CSDN博客_springboot拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
}
}
addPathPatterns指明需要拦截的url,excludePathPatterns则相反(不需拦截)。
7.7 Ajax与Controller交互
Ajax:Asynchronous Javascript And XML,异步JavaScript和XML。
使用前需要在对interceptors的配置中将资源文件排除在外。关于页面的详细示例代码见P162~P163,由于还没有学习过JavaScript语言,这里先略过。主要学习两个注解:
@RequestBody:作用在形参列表上,将前台发送数据封装为JavaBean对象。
@ResponseBody:作用在方法上,表示方法返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。