📜  Spring MVC教程(1)

📅  最后修改于: 2023-12-03 15:20:13.403000             🧑  作者: Mango

Spring MVC教程

Spring MVC(Model-View-Controller)是一种Java Web框架。它通过使用 Servlet API 和 JavaServer Pages(JSP)技术来实现 Web 应用程序。 在本教程中,您将学习如何使用Spring MVC来创建Web应用程序。

目录
环境搭建

在学习Spring MVC之前,您需要先搭建好开发环境。这里我们使用Maven来创建项目,如果您还未安装Maven,请参考Maven安装教程

创建Spring MVC项目

使用Maven创建Spring MVC项目非常容易。只需要执行下列命令即可:

mvn archetype:generate -DgroupId=com.example -DartifactId=spring-mvc-demo -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

上面的命令指定了项目包名为com.example,项目名称为spring-mvc-demo,项目类型为Maven WebApp。

Spring MVC架构概述

在Spring MVC中,客户端通过发送HTTP请求来与应用程序交互。控制器(Controller)负责处理对应的请求,完成相应的处理逻辑后,将处理结果转发到视图(View)中进行渲染,最后将渲染后的结果返回到客户端。

Spring MVC中主要分为以下几个部分:

  • DispatcherServlet:负责请求的分发和响应的转发。
  • HandlerMapping:用于确定请求所对应的处理器(Handler)。
  • HandlerAdapter:用于将请求转发给相应的Handler进行处理。
  • HandlerInterceptor:拦截请求并进行处理。
  • ViewResolver:将处理结果渲染到客户端页面。
控制器和处理程序映射

在Spring MVC中,控制器负责处理请求,并将处理结果转发给视图进行渲染。

我们可以通过注解让Spring自动将请求映射到相应的控制器处理程序方法。例如:

@Controller
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping(method = RequestMethod.GET)
    public String hello(ModelMap model) {
        model.addAttribute("message", "Hello Spring MVC Framework!");
        return "hello";
    }

}

上述代码中,使用@Controller注解将类标记为控制器,使用@RequestMapping注解设置请求的路径。Spring会根据注解中的请求路径自动映射到该控制器的hello方法中进行处理。

HTTP请求处理

Spring MVC支持多种类型的HTTP请求处理方式,包括form-data、x-www-form-urlencoded、application/json和xml等。

通过使用@RequestBody注解,我们可以获取请求体中的内容,并进行处理。

@RequestMapping(value = "/users", method = RequestMethod.POST)
public String createUser(@RequestBody User user, ModelMap model) {
    userService.addUser(user);
    model.addAttribute("user", user);
    return "success";
}

上述代码中,我们首先通过@RequestBody注解获取请求体中的JSON或XML内容,将其转换为User对象,然后再调用userService的方法将用户信息添加到数据库中。

返回HTTP响应

对于HTTP响应,Spring MVC支持多种返回类型,包括String、ModelAndView、RedirectView和@ResponseBody等。我们可以根据实际需要返回相应的类型。

@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello(ModelMap model) {
    model.addAttribute("message", "Hello Spring MVC Framework!");
    return "hello";
}

@RequestMapping(value = "/users", method = RequestMethod.GET)
public ModelAndView getUsers() {
    List<User> userList = userService.getUsers();
    ModelAndView mav = new ModelAndView();
    mav.setViewName("userList");
    mav.addObject("userList", userList);
    return mav;
}

@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
@ResponseBody
public Map<String, String> deleteUser(@PathVariable("id") int id) {
    User user = userService.getUserById(id);
    userService.deleteUser(user);
    Map<String, String> result = new HashMap<>();
    result.put("status", "ok");
    result.put("message", "User deleted successfully");
    return result;
}

上述代码中,hello方法返回一个字符串类型,即将渲染在客户端页面的视图名。其它方法则分别返回ModelAndView和@ResponseBody类型。

视图解析器

视图解析器(View Resolver)负责将控制器处理后的结果渲染到客户端页面。Spring MVC支持多种视图解析器,包括InternalResourceViewResolver、FreeMarkerViewResolver和VelocityViewResolver等。

例如,我们可以使用InternalResourceViewResolver来将JSP页面渲染到客户端页面。

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

上述代码中,我们将视图路径设置为/WEB-INF/views/目录下的JSP文件,并将文件后缀名设置为.jsp

表单处理

在Spring MVC中,我们可以方便地处理表单中的数据。首先,在表单中设置相应的控件,方法如下:

<form:form action="/submitForm" method="post" modelAttribute="userForm">
    <table>
        <tr>
            <td><form:label path="username">Username</form:label></td>
            <td><form:input path="username" /></td>
        </tr>
        <tr>
            <td><form:label path="password">Password</form:label></td>
            <td><form:password path="password" /></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

上述代码中,我们创建了一个表单,其中包含了一个用户名的输入框和一个密码的输入框。使用modelAttribute属性将表单数据绑定到一个JavaBean中。

然后,在控制器中定义与之对应的处理方法。

@RequestMapping(value = "/submitForm", method = RequestMethod.POST)
public String submitForm(@ModelAttribute("userForm") UserForm userForm, ModelMap model) {
    userService.addUser(userForm.getUsername(), userForm.getPassword());
    model.addAttribute("username", userForm.getUsername());
    return "success";
}

注意,@ModelAttribute注解中设置的值必须与前端表单中的modelAttribute属性值相同。

文件上传

文件上传在Web开发中常常使用。Spring MVC提供了MultipartResolver类来支持文件上传。当用户上传了一个文件时,MultipartResolver会将文件保存到一个临时目录中,并提供相应的API来获取上传的文件。

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadFile(@RequestParam("file") MultipartFile file, ModelMap model) {
    try {
        byte[] bytes = file.getBytes();
        //保存到数据库或文件系统
    } catch (IOException e) {
        e.printStackTrace();
    }
    model.addAttribute("message", "File uploaded successfully: " + file.getOriginalFilename());
    return "success";
}

上述代码中,@RequestParam注解指定了上传的文件名为file,并将文件保存到byte数组中。

拦截器

在Spring MVC中,我们可以使用拦截器(HandlerInterceptor)来拦截并处理请求。

拦截器主要分为三个阶段,在请求被处理之前、正在处理请求、处理请求之后。每个阶段对应一个方法:preHandle、postHandle和afterCompletion。

public class LoginInterceptor implements HandlerInterceptor {
   
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("USER");
        if (user == null) {
            response.sendRedirect(request.getContextPath() + "/login");
            return false;
        }
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }
}

上述代码中,我们创建了一个名为LoginInterceptor的拦截器,在preHandle方法中判断当前用户是否已登录。如果未登录,则重定向到登录页面。

对于上面的拦截器,我们需要将该拦截器注册到全局中。

<mvc:interceptors>
    <bean class="com.example.interceptor.LoginInterceptor" />
</mvc:interceptors>

注意,在Spring MVC中,如果您使用的是Servlet 3.0及以上容器,则可以使用@WebFilter注解来定义拦截器。

国际化

Spring MVC支持通过国际化(I18n)来支持多语言。我们可以在配置文件中定义多个Properties文件来存储多个语言版本的内容。

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="messages" />
</bean>

上述代码中,我们将消息源的基础名称设置为messages,表示消息资源文件的基础名称为messages。

我们可以在Properties文件中设置多种语言版本的消息内容。

greeting=Hello!

上述代码中,我们在Properties文件中设置了问候语。如果需要支持多个语言版本,则可以定义多个Properties文件。

greeting=你好!

上述代码为中文语言版本下的问候语。当我们需要在视图中获取国际化消息时,只需使用<spring:message>标签即可。

<h1><spring:message code="greeting" /></h1>

上述代码中,我们使用了<spring:message>标签来获取问候语。

Spring MVC常用注解

Spring MVC提供了多种注解来简化代码编写。这些注解包括但不限于:

  • @Controller:用于标记控制器。
  • @RequestMapping:用于设置请求路径。
  • @PathVariable:用于获取请求路径中的参数。
  • @RequestParam:用于获取请求参数。
  • @ResponseBody:用于直接返回HTTP响应。
  • @ModelAttribute:用于绑定请求数据到JavaBean中。
  • @SessionAttributes:用于将数据存储到Session中,方便多个请求同时访问。
总结

在本教程中,我们通过一个示例项目学习了Spring MVC的基本原理。我们了解了Spring MVC的架构、控制器和处理程序映射、HTTP请求处理、返回HTTP响应、视图解析器、表单处理、文件上传、拦截器、国际化以及常见注解等。

希望通过本教程能够帮助您了解Spring MVC并快速入门。