答辩学网站开发知识能力要求,漳州企业网站建设公司,网站做扫一扫,一站式网站手机端怎么做常用注解
PathVariable#xff1a;用于从URL路径中提取变量。RequestHeader#xff1a;用于从HTTP请求头中获取数据。ModelAttribute#xff1a;用于获取请求参数#xff08;包括URL参数和POST请求的表单数据#xff09;#xff0c;也可以用于将数据绑定到对象上。Reque…常用注解
PathVariable用于从URL路径中提取变量。RequestHeader用于从HTTP请求头中获取数据。ModelAttribute用于获取请求参数包括URL参数和POST请求的表单数据也可以用于将数据绑定到对象上。RequestParam用于获取URL参数。CookieValue用于获取请求中的Cookie值。RequestBody用于获取请求体中的数据通常用于处理POST请求中的JSON或XML数据。
java代码示例(普通)
import org.springframework.web.bind.annotation.*;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;RestController
RequestMapping(/api)
public class DataController {// 使用 PathVariable 从URL路径中获取变量GetMapping(/path/{userId}/profile)public String getPathVariable(PathVariable String userId) {return User ID from Path Variable: userId;}// 使用 RequestHeader 从请求头中获取数据GetMapping(/header)public String getRequestHeader(RequestHeader(X-Request-ID) String requestId) {return Request ID from Header: requestId;}// 使用 ModelAttribute 获取请求参数并绑定到对象PostMapping(/modelAttribute)public String handleModelAttribute(ModelAttribute User user) {return User Name: user.getName() , Age: user.getAge();}// 使用 RequestParam 获取URL参数GetMapping(/params)public String getRequestParam(RequestParam(name) String name, RequestParam(age) int age) {return Name: name , Age: age;}// 使用 CookieValue 获取Cookie值GetMapping(/cookie)public String getCookieValue(CookieValue(session) String sessionCookie) {return Session Cookie: sessionCookie;}// 使用 RequestBody 获取请求体中的数据PostMapping(/body)public String handleRequestBody(RequestBody User user) {return User Name from Body: user.getName() , Age: user.getAge();}static class User {private String name;private int age;// Getters and setterspublic String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}}
}测试示例(普通)
PathVariable 测试路径
GET /api/path/123/profileRequestHeader 测试路径
GET /api/header
请求头中需要包含 X-Request-ID: 12345。ModelAttribute 测试路径
POST /api/modelAttribute
{name: John Doe,age: 30
}RequestParam 测试路径
GET /api/params?nameJohnage30CookieValue 测试路径
GET /api/cookie
Cookie: sessionabc123RequestBody 测试路径
POST /api/body
{name: Jane Doe,age: 25
}特殊(传数组)
使用 RequestBody 传递JSON数组 如果你使用POST请求并通过请求体传递一个JSON数组你可以使用RequestBody注解来接收这个数组。在Spring Boot中你可以使用HttpEntity或者直接使用RequestBody来接收数组。 RestController
RequestMapping(/api)
public class ListController {// 使用 RequestBody 接收JSON数组PostMapping(/list)public String handleRequestBodyList(RequestBody ListUser users) {return Received users.size() users;}
}测试路径和请求体 POST /api/list
[{name: John Doe, age: 30},{name: Jane Doe, age: 25}
]使用 RequestParam 传递多个相同参数 如果你使用GET请求并通过URL参数传递多个相同名称的参数你可以使用RequestParam注解来接收这些参数并将其转换为列表。 RestController
RequestMapping(/api)
public class ListController {// 使用 RequestParam 接收多个相同参数GetMapping(/params)public String getRequestParamList(RequestParam(userId) ListString userIds) {return Received user IDs: Arrays.toString(userIds.toArray());}
}测试路径和参数 GET /api/params?userId1userId2userId3使用 ModelAttribute 传递表单数据 如果你使用POST请求并通过表单数据传递一个列表你可以使用ModelAttribute注解来接收这个列表。这通常用于处理表单提交。 RestController
RequestMapping(/api)
public class ListController {// 使用 ModelAttribute 接收表单数据PostMapping(/form)public String handleModelAttribute(ModelAttribute ListUser users) {return Received users.size() users;}
}测试路径和请求体 POST /api/form
请求体中包含表单数据使用application/x-www-form-urlencoded
userId1userId2userId3
或者如果你使用JSON格式的请求体你需要自定义一个包装类来接收这个列表。使用自定义包装类 对于复杂的数据结构你可以创建一个自定义的包装类来接收列表。 public class UserListWrapper {private ListUser users;// Getters and setterspublic ListUser getUsers() {return users;}public void setUsers(ListUser users) {this.users users;}
}RestController
RequestMapping(/api)
public class ListController {// 使用自定义包装类接收JSON数组PostMapping(/custom)public String handleCustomList(RequestBody UserListWrapper wrapper) {return Received wrapper.getUsers().size() users;}
}测试路径和请求体 POST /api/custom
{users: [{name: John Doe, age: 30},{name: Jane Doe, age: 25}]
}原理分析
主要是DispatcherServlet 的doDispatch方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 获取当前请求的HandlerMappedHandler mappedHandler getHandler(processedRequest);if (mappedHandler null) {noHandlerFound(processedRequest, response);return;}// 获取HandlerAdapterHandlerAdapter ha getHandlerAdapter(mappedHandler.getHandler());// 执行前置拦截器if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 调用Handler包含参数解析器处理参数过程ModelAndView mv ha.handle(processedRequest, response, mappedHandler.getHandler());}在handle方法内部HandlerAdapter会使用一系列的参数解析器HandlerMethodArgumentResolver来处理Controller方法的参数。这些解析器负责从请求中提取数据并将其转换为Controller方法所需的参数类型。
参数解析的主要代码位于RequestMappingHandlerAdapter的handleInternal方法中
protected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;checkRequest(request);// 如果synchronizeOnSession为true且能从request获取会话对象则以同步方式执行handlerif (this.synchronizeOnSession) {HttpSession session request.getSession(false);if (session ! null) {Object mutex WebUtils.getSessionMutex(session);synchronized (mutex) {mav invokeHandlerMethod(request, response, handlerMethod);}} else {mav invokeHandlerMethod(request, response, handlerMethod);}} else {mav invokeHandlerMethod(request, response, handlerMethod);}if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {return null;}applyDefaultViewName(request, mav);MappedHandler mappedHandler getHandlerExecutionChain(handlerMethod);mappedHandler.applyPostHandle(request, response, mav);return mav;
}在invokeHandlerMethod方法中会遍历所有的参数解析器寻找能够解析当前参数的解析器并将其缓存。然后通过参数解析器将需要的参数从请求中获取出来并进行类型转换和数据绑定。
public Object invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletInvocableHandlerMethod invocableMethod createInvocableHandlerMethod(handlerMethod);invocableMethod.invokeAndHandle(request, response);return invocableMethod.getReturnValue();
}在ServletInvocableHandlerMethod的invokeAndHandle方法中会调用getMethodArgumentValues方法来获取参数值这个方法会遍历所有的参数解析器使用它们来解析参数。
public Object[] getMethodArgumentValues(NativeWebRequest request, Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {MethodParameter[] parameters getMethodParameters();if (ObjectUtils.isEmpty(parameters)) {return EMPTY_ARGS;}Object[] args new Object[parameters.length];for (int i 0; i parameters.length; i) {MethodParameter parameter parameters[i];parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);args[i] findProvidedArgument(parameter, providedArgs);if (args[i] null) {HandlerMethodArgumentResolver resolver this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);args[i] resolver.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);}}return args;
}在这个方法中resolvers.resolveArgument会调用具体的参数解析器来解析参数。这些解析器主要有
RequestParamMethodArgumentResolver处理RequestParam注解的参数。PathVariableMethodArgumentResolver处理PathVariable注解的参数。RequestBodyMethodArgumentResolver处理RequestBody注解的参数通常用于接收JSON或XML格式的请求体。RequestHeaderMethodArgumentResolver处理RequestHeader注解的参数。CookieValueMethodArgumentResolver处理CookieValue注解的参数。 每个解析器都实现了HandlerMethodArgumentResolver接口它们负责从请求中提取数据并将其转换为Controller方法所需的参数类型。