如果在使用 @Controller
标注的控制器中出现404错误而在使用 @RestController
中正常工作,可能是由于以下原因:
- 返回类型不同:
@RestController
注解的控制器方法返回的是数据,而不是视图。它会将返回的数据直接写入HTTP响应体中,通常是JSON格式。@Controller
注解的控制器方法通常返回视图名称,而不是数据。如果没有配置正确的视图解析器,可能会导致404错误。
- 视图解析器配置:
- 确保在使用
@Controller
时配置了正确的视图解析器,以将逻辑视图名称解析为实际的视图。例如,通过配置InternalResourceViewResolver
或ThymeleafViewResolver
,具体取决于你使用的视图技术。
- 确保在使用
- 路径映射和视图名称:
- 确保
@Controller
中的@RequestMapping
或@GetMapping
注解中指定的路径映射和视图名称的返回与你的项目结构和配置相匹配。
- 确保
示例代码:
javaCopy code@Controller
public class MyController {
@GetMapping("/view")
public String getView() {
return "myView"; // 确保视图名称正确
}
}
- 静态资源配置:
- 如果在
@Controller
中使用了@RequestMapping
指定路径,确保不与静态资源路径冲突。Spring Boot默认会映射/static
、/public
、/resources
和/META-INF/resources
为静态资源路径。
- 如果在
Bean type | Explanation |
---|---|
HandlerMapping | 处理器 (Controller) 的映射。保存了每个Controller的所有方法都能处理哪些请求。 利用map,保存请求url和controller的对应关系: 所有的映射存在 MappingReqistry 类中。里面有很多map进行配合 最终返回的是一个 HandlerExecutionChain 处理器链[handler (真正处理请求的目标方法)interceptors (所有拦截器) : 效果,目标方法执行前后由拦截器进行拦截] |
HandlerAdapter | 就是一个超级反射工具。用它来反射执行目标方法 执行目标方法期间。确定方法的每个参数的值、把返回值封装成ModeLAndviewSimpleControllerHandlerAdapter SimpleControllerHandlerAdapter 用于支持实现 Controller 接口的控制器,RequestMappingHandlerAdapter 用于支持注解式的控制器,如 @Controller 或 `@RestController |
HandlerExceptionResolver | 异常解析器: 利用所有的异常解析看谁能解析这个异常。 把异常转成一个 ModeLAndView; 全局异常处理; @ControllerAdvice、@ExceptionHandler; 比如: ExceptionHandlerExceptionResolver 异常解析器的作用就是 全局找 所有标注了@ExceptionHandler 注解的方法,看谁能处理这个异常s |
ViewResolver | string 的逻辑视图 (页面地址) ,转化为真实 View; 并染 详见 View Resolution and View Technologies . 比如: BeanNameviewResolver: Bean名字视图解析器,把返回值当前组件的名字去容器中找这个名字的View组件。 UrLBasedViewResolver: 前缀 + 返回值 + 后缀 如果有forward:前缀。new InternalResourceView(forwardUrl);<br如果有redirect:前缀。new RedirectView(你的路径); 在底层调用response.sendRedirect(encodedURL]: |
LocaleResolver LocaleContextResolver | 国际化的解析器 |
ThemeResolver | 主题解析器 |
MultipartResolver | 文件上传解析器。负责在请求一进来就检查是否文件上传请求,如果是就包装成一个AbstractMultipartHttpServletRequest; 方便以后使用 |
FlashMapManager | 洋细看 Flash Attributes . 重定向携带数据;放到session中共享数据 |
简易版 Servlet
package com.example.springbootstudy.MVC_servelt_lesson;
import jdk.internal.vm.compiler.collections.EconomicMap;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Myserver {
// private ServerSocket serverSocket;
public static void main(String[] args) throws IOException {
String portName ="";
Integer port=8080;
ServerSocket serverSocket=new ServerSocket(port);
while (true){
Socket socket=serverSocket.accept();
try {
handler1(socket);
}catch (Exception e){
e.printStackTrace();
serverSocket.close();
}
}
}
public static void handler1(Socket socket) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
InputStream inputStream = socket.getInputStream();
byte[] buff=new byte[1024];
inputStream.read(buff);
String content =new String(buff);
String substring = content.substring(0, content.indexOf("\r\n"));
// GET /admin
String[] s = substring.split(" ");
String method=s[0];
String path=s[1];
String className=path+"Servlet";
Servlet servlet =(Servlet) Class.forName(className).newInstance();
servlet.service(new HttpRequest(content),new HttpResponse(socket));
socket.close();
}
}
Spring MVC(Model-View-Controller)框架遵循一个明确定义的请求处理流程。以下是该过程的逐步详解:
- 请求映射(Handler Mapping):
- 当请求进来时,DispatcherServlet 会查询 HandlerMapping 以确定哪个控制器应该处理请求。
- HandlerMapping 将请求的URL映射到特定的控制器方法(处理程序)。
- 处理程序执行链:
- 如果找到了合适的处理程序,HandlerMapping 返回一个 HandlerExecutionChain,其中包含选定的处理程序(控制器方法)和与之关联的任何拦截器。
- 处理程序适配器:
- 然后,DispatcherServlet 调用 HandlerAdapter,负责执行处理程序方法。HandlerAdapter 将请求转换为处理程序方法可以理解的格式。
- 对于注解控制器,通常使用反射来调用适当的方法。
- 拦截器(PreHandle):
- 在实际处理程序方法执行之前,框架调用 HandlerExecutionChain 中任何拦截器的 preHandle 方法。
- 如果任何 preHandle 方法返回 false,请求处理停止,并返回响应。
- 处理程序执行:
- 执行实际的处理程序方法以处理请求。
- 处理程序方法通常执行业务逻辑并返回一个 ModelAndView 对象,其中包含模型(数据)和视图(呈现)。
- 拦截器(PostHandle):
- 在执行处理程序方法后,调用拦截器的 postHandle 方法。
- 拦截器有机会在呈现 ModelAndView 之前对其进行操作。
- 视图解析:
- DispatcherServlet 查询 ViewResolver 以确定根据ModelAndView中的逻辑视图名称要呈现的实际视图。
- 视图负责呈现响应,可以是HTML页面、JSON、XML等。
- 异常处理:
- 如果在处理请求过程中发生异常,它将由配置的异常解析器处理。
- 异常解析器将异常映射到适当的错误视图或执行其他配置的操作。
- 拦截器(AfterCompletion):
- 最后,在视图呈现后,调用拦截器的 afterCompletion 方法。
- 无论是否发生异常,都会调用此方法。
- 错误处理:
- 如果有任何未处理的异常,框架可能会调用全局错误处理机制,例如错误页面或自定义错误处理组件。