Spring MVC 重点整理
Spring MVC框架(重点整理)
1. 大家好
2. Spring MVC 中的配置文件,名字是可以指定的,位置也是可以指定的,怎么指定?
在 Spring MVC 里,DispatcherServlet
是核心前端控制器,其配置文件的指定一般是在 web.xml
中借助 init-param
来完成。下面是详细的配置示例:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 通过 contextConfigLocation 指定配置文件的位置和名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 可以指定具体的类路径,这里假设配置文件在类路径根目录下名为 springmvc-config.xml -->
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 这里配置 DispatcherServlet 拦截的请求路径 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
上述配置中,contextConfigLocation
指明了 Spring MVC 配置文件的具体位置与名称。你可以根据实际需求,把配置文件放置在不同的目录下,并且使用不同的文件名。
3. @RequestMapping 注解可以出现在类上,也可以出现在方法上,例如:
@RequestMapping
注解的用途是将请求映射到控制器的处理方法。它既能够用在类上,也可以用在方法上。以下是示例代码:
@Controller
// 类上的 @RequestMapping 为该控制器下的所有处理方法设置了全局的请求路径前缀
@RequestMapping("/user")
public class UserController {
// 方法上的 @RequestMapping 指定了具体的请求路径,结合类上的路径,完整路径为 /user/add
@RequestMapping("/add")
public String addUser() {
return "addUser";
}
// 结合类上的路径,完整路径为 /user/delete
@RequestMapping("/delete")
public String deleteUser() {
return "deleteUser";
}
}
在这个示例中,类 UserController
上的 @RequestMapping("/user")
为所有处理方法设定了全局路径前缀,而方法上的 @RequestMapping
则指定了具体的请求路径。
4. 关于 @RequestMapping 注解的 value 属性
@RequestMapping
注解的 value
属性用于指定请求的 URL 路径。它是 @RequestMapping
注解的默认属性,所以在使用时可以省略属性名。示例如下:
@Controller
public class ProductController {
// 这里省略了 value 属性名,直接写路径
@RequestMapping("/product/list")
public String listProducts() {
return "productList";
}
// 也可以显式写出 value 属性
@RequestMapping(value = "/product/detail")
public String showProductDetail() {
return "productDetail";
}
}
5. RequestMapping 的 value 属性支持 Ant 风格的,支持模糊匹配的路径
@RequestMapping
的 value
属性支持 Ant 风格的路径表达式,这种表达式能实现模糊匹配。常见的 Ant 风格通配符有:
?
:匹配单个字符。*
:匹配任意数量的任意字符,但不包含路径分隔符/
。**
:匹配任意数量的任意字符,包括路径分隔符/
。
示例代码如下:
@Controller
public class FileController {
// 匹配 /file/test.txt 等
@RequestMapping("/file/*.txt")
public String handleTxtFiles() {
return "txtFiles";
}
// 匹配 /file/dir1/test.txt、/file/dir1/dir2/test.txt 等
@RequestMapping("/file/**/*.txt")
public String handleNestedTxtFiles() {
return "nestedTxtFiles";
}
// 匹配 /file/a.txt、/file/b.txt 等
@RequestMapping("/file/?.*")
public String handleSingleCharFiles() {
return "singleCharFiles";
}
}
6. 关于 @RequestMapping 注解的 value 属性上的占位符(重点)
@RequestMapping
的 value
属性支持使用占位符,占位符通常用 {}
包裹。在处理方法中,可以使用 @PathVariable
注解来获取占位符中的值。示例如下:
@Controller
public class OrderController {
// 使用占位符 {orderId}
@RequestMapping("/order/{orderId}")
public String showOrderDetail(@PathVariable("orderId") String orderId) {
System.out.println("Order ID: " + orderId);
return "orderDetail";
}
}
在这个示例中,{orderId}
是占位符,@PathVariable("orderId")
注解将请求路径中的实际值绑定到方法参数 orderId
上。
7. 关于 @RequestMapping 注解的 method 属性,通过该属性可以限制前端发送的请求方式。如果前端发送的请求方式与后端的处理方式不同,则出现 405 错误
@RequestMapping
的 method
属性能够限制请求的方式,如 GET
、POST
、PUT
、DELETE
等。若前端请求方式与后端处理方法不匹配,就会返回 405 状态码。示例如下:
@Controller
public class UserController {
// 只处理 GET 请求
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser() {
return "getUser";
}
// 只处理 POST 请求
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String createUser() {
return "createUser";
}
}
8. 衍生 Mapping
Spring 提供了一些衍生注解,这些注解是 @RequestMapping
的简化形式,能更清晰地表明请求方法。具体如下:
@GetMapping
:等同于@RequestMapping(method = RequestMethod.GET)
。@PostMapping
:等同于@RequestMapping(method = RequestMethod.POST)
。@PutMapping
:等同于@RequestMapping(method = RequestMethod.PUT)
。@DeleteMapping
:等同于@RequestMapping(method = RequestMethod.DELETE)
。@PatchMapping
:等同于@RequestMapping(method = RequestMethod.PATCH)
。
示例代码如下:
@Controller
public class ProductController {
@GetMapping("/product")
public String getProduct() {
return "getProduct";
}
@PostMapping("/product")
public String createProduct() {
return "createProduct";
}
}
9. web 的请求方式
常见的 Web 请求方式有:
- GET:用于获取资源,请求参数会附加在 URL 后面,有长度限制,不安全。
- POST:用于提交数据,请求参数在请求体中,无长度限制,相对安全。
- PUT:用于更新资源,通常要求请求包含完整的资源信息。
- DELETE:用于删除资源。
- PATCH:用于部分更新资源,只提交需要更新的部分。
- HEAD:与 GET 类似,但只返回响应头,不返回响应体。
- OPTIONS:用于获取服务器支持的请求方法等信息。
10. 关于 RequestMapping 注解的 params 属性
@RequestMapping
的 params
属性用于限制请求中必须包含某些参数,或者参数的值必须满足特定条件。示例如下:
@Controller
public class SearchController {
// 要求请求中必须包含 keyword 参数
@RequestMapping(value = "/search", params = "keyword")
public String searchWithKeyword() {
return "searchWithKeyword";
}
// 要求请求中包含 page 参数,且 page 的值为 1
@RequestMapping(value = "/search", params = "page=1")
public String searchFirstPage() {
return "searchFirstPage";
}
}
11. 关于 RequestMapping 注解的 headers 属性
@RequestMapping
的 headers
属性用于限制请求头中必须包含某些头信息,或者头信息的值必须满足特定条件。示例如下:
@Controller
public class ApiController {
// 要求请求头中包含 Accept 字段,且值为 application/json
@RequestMapping(value = "/api/data", headers = "Accept=application/json")
public String getDataAsJson() {
return "dataAsJson";
}
// 要求请求头中包含 X-Requested-With 字段,且值为 XMLHttpRequest(常用于 AJAX 请求)
@RequestMapping(value = "/api/ajax", headers = "X-Requested-With=XMLHttpRequest")
public String handleAjaxRequest() {
return "ajaxResponse";
}
}
12. 获取请求提交的数据
在 Spring MVC 中,获取请求提交的数据有多种方式:
- 使用
@RequestParam
注解:用于获取请求参数,适用于 GET 和 POST 请求。示例如下:
@Controller
public class LoginController {
@RequestMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
System.out.println("Username: " + username + ", Password: " + password);
return "loginResult";
}
}
- 使用实体类接收参数:如果请求参数较多,可以创建一个实体类,Spring MVC 会自动将请求参数绑定到实体类的属性上。示例如下:
public class User {
private String username;
private String password;
// 省略 getter 和 setter 方法
}
@Controller
public class RegisterController {
@RequestMapping("/register")
public String register(User user) {
System.out.println("Username: " + user.getUsername() + ", Password: " + user.getPassword());
return "registerResult";
}
}
- 使用
@RequestBody
注解:用于获取 POST 请求的请求体数据,通常用于处理 JSON 或 XML 格式的数据。示例如下:
@Controller
public class JsonController {
@RequestMapping(value = "/json", method = RequestMethod.POST)
public String handleJson(@RequestBody User user) {
System.out.println("Username: " + user.getUsername() + ", Password: " + user.getPassword());
return "jsonResult";
}
}
13. 获取请求头信息?
在 Spring MVC 中,可以使用 @RequestHeader
注解来获取请求头信息。示例如下:
@Controller
public class HeaderController {
@RequestMapping("/headers")
public String getHeaders(@RequestHeader("User-Agent") String userAgent,
@RequestHeader("Accept-Language") String acceptLanguage) {
System.out.println("User-Agent: " + userAgent);
System.out.println("Accept-Language: " + acceptLanguage);
return "headersResult";
}
}
14. 获取客户端提交的 Cookie?
可以使用 @CookieValue
注解来获取客户端提交的 Cookie。示例如下:
@Controller
public class CookieController {
@RequestMapping("/cookies")
public String getCookies(@CookieValue("JSESSIONID") String sessionId) {
System.out.println("JSESSIONID: " + sessionId);
return "cookiesResult";
}
}
15. 关于 javaweb 项目中,get 请求的乱码问题?
在 JavaWeb 项目中,GET 请求的乱码问题通常是由于 URL 编码不一致导致的。解决方法是修改 Tomcat 的 server.xml
文件,在 Connector
元素中添加 URIEncoding="UTF-8"
属性。示例如下:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
16. 关于 javaweb 项目中,post 请求的乱码问题?
POST 请求的乱码问题一般是因为请求体的编码与服务器端的编码不一致。可以通过配置 CharacterEncodingFilter
来解决。在 web.xml
中添加如下配置:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
17. request 域:
request
域是一次请求范围内的存储区域,用于在同一个请求的不同处理环节之间传递数据。在 Spring MVC 中,可以通过 HttpServletRequest
对象来操作 request
域。示例如下:
@Controller
public class RequestScopeController {
@RequestMapping("/requestScope")
public String setRequestAttribute(HttpServletRequest request) {
request.setAttribute("message", "This is a request scope message");
return "requestScopeResult";
}
}
在 JSP 页面中可以通过 request.getAttribute("message")
来获取存储在 request
域中的数据。
18. session 域
session
域是一次会话范围内的存储区域,用于在同一个用户的多个请求之间传递数据。在 Spring MVC 中,可以通过 HttpSession
对象来操作 session
域。示例如下:
@Controller
public class SessionScopeController {
@RequestMapping("/sessionScope")
public String setSessionAttribute(HttpServletRequest request) {
HttpSession session = request.getSession();
session.setAttribute("user", "John");
return "sessionScopeResult";
}
}
在 JSP 页面中可以通过 session.getAttribute("user")
来获取存储在 session
域中的数据。
19. application 域
application
域是整个应用程序范围内的存储区域,所有用户共享该区域的数据。在 Spring MVC 中,可以通过 ServletContext
对象来操作 application
域。示例如下:
@Controller
public class ApplicationScopeController {
@RequestMapping("/applicationScope")
public String setApplicationAttribute(HttpServletRequest request) {
ServletContext application = request.getServletContext();
application.setAttribute("appName", "My Application");
return "applicationScopeResult";
}
}
在 JSP 页面中可以通过 application.getAttribute("appName")
来获取存储在 application
域中的数据。
20. SpringMVC 中常用的视图:
- JSP 视图:传统的 Java 服务器页面,通过
InternalResourceViewResolver
配置使用。示例配置如下:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
- JSON 视图:用于返回 JSON 数据,通常使用
MappingJackson2JsonView
或通过@ResponseBody
注解结合 Jackson 库实现。示例代码如下:
@Controller
public class JsonViewController {
@RequestMapping("/jsonView")
@ResponseBody
public User getJsonUser() {
User user = new User();
user.setUsername("John");
user.setPassword("123456");
return user;
}
}
- Redirect 视图:用于重定向到另一个 URL,返回的视图名以
redirect:
开头。示例如下:
@Controller
public class RedirectController {
@RequestMapping("/redirect")
public String redirectToAnotherPage() {
return "redirect:/anotherPage";
}
}
- Forward 视图:用于转发到另一个 URL,返回的视图名以
forward:
开头。示例如下:
@Controller
public class ForwardController {
@RequestMapping("/forward")
public String forwardToAnotherPage() {
return "forward:/anotherPage";
}
}
21. 实现视图机制的核心类与核心接口
ViewResolver
接口:负责将逻辑视图名解析为具体的View
对象。常见的实现类有InternalResourceViewResolver
、ContentNegotiatingViewResolver
等。View
接口:表示具体的视图,负责将模型数据渲染为响应内容。常见的实现类有InternalResourceView
(用于 JSP 视图)、MappingJackson2JsonView
(用于 JSON 视图)等。
22. 在 SpringMVC 中是怎么通过代码完成转发的?怎么完成重定向的?
- 转发:在处理方法中返回以
forward:
开头的视图名,示例如下:
@Controller
public class ForwardExampleController {
@RequestMapping("/forwardExample")
public String forwardToPage() {
return "forward:/targetPage";
}
}
- 重定向:在处理方法中返回以
redirect:
开头的视图名,示例如下:
@Controller
public class RedirectExampleController {
@RequestMapping("/redirectExample")
public String redirectToPage() {
return "redirect:/targetPage";
}
}
23. mvc:view-controller
<mvc:view-controller>
标签用于简化配置,直接将 URL 映射到视图,无需编写控制器方法。示例配置如下:
<mvc:view-controller path="/welcome" view-name="welcomePage"/>
上述配置将 /welcome
请求直接映射到 welcomePage
视图。
24. mvc:annotation-driven/
<mvc:annotation-driven>
标签用于开启 Spring MVC 的注解驱动功能,它会自动注册一些必要的组件,如 RequestMappingHandlerMapping
、RequestMappingHandlerAdapter
等,支持使用 @RequestMapping
等注解。示例配置如下:
<mvc:annotation-driven/>
25. 关于静态资源处理:
在 Spring MVC 中,默认情况下 DispatcherServlet
会拦截所有请求,包括静态资源请求。可以通过 <mvc:resources>
标签来配置静态资源的处理。示例如下:
<mvc:resources mapping="/static/**" location="/static/"/>
上述配置将 /static/
目录下的所有静态资源(如 CSS、JS、图片等)映射到 /static/**
路径。
26. 什么是 RESTFul?
RESTful(Representational State Transfer)是一种软件架构风格,用于设计网络应用程序的 API。它的主要特点包括:
- 资源导向:使用 URL 来标识资源,如
/users
表示用户资源集合,/users/1
表示 ID 为 1 的用户资源。 - 使用 HTTP 方法:通过不同的 HTTP 请求方法(
GET
、POST
、PUT
、DELETE
)来对资源进行操作,如GET /users
获取所有用户,POST /users
创建新用户。 - 无状态:每个请求都是独立的,服务器不保存客户端的状态信息。
- 统一接口:使用统一的接口进行资源操作,便于客户端和服务器之间的交互。
27. RESTful 编程风格中要求,修改的时候,必须提交 PUT 请求,怎么提交 PUT 请求呢?
在浏览器中,表单默认只支持 GET
和 POST
请求,要提交 PUT
请求,可以通过以下两种方式:
- 使用 Spring 的
HiddenHttpMethodFilter
:在表单中添加一个隐藏字段_method
,并将其值设置为PUT
。同时,在web.xml
中配置HiddenHttpMethodFilter
。示例如下:
<form action="/users/1" method="post">
<input type="hidden" name="_method" value="PUT"/>
<!-- 其他表单字段 -->
<input type="submit" value="Update User"/>
</form>
<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>
- 使用 AJAX 请求:通过 JavaScript 的
XMLHttpRequest
或 jQuery 的$.ajax
方法发送PUT
请求。示例如下:
$.ajax({
url: '/users/1',
type: 'PUT',
data: {
// 请求数据
},
success: function(response) {
console.log('Update success');
},
error: function(error) {
console.log('Update failed');
}
});
Spring 生态是以 Spring Framework 为核心,衍生出的一系列相互关联、功能互补的技术和工具集合,用于简化企业级应用开发,覆盖从单体应用到分布式微服务、从 Web 开发到数据处理等诸多场景。