Srping MVC中Controller的void方法声明误区

Srping MVC中Controller的void方法声明误区

Controller中定义void方法,这种场景一般是通过HttpServletResponse对象来输出页面内容。注意:Controller的void方法中一定要声明HttpServletResponse类型的方法入参!
void方法不定义HttpServletResponse类型的入参,HttpServletResponse对象通过RequestContextHolder上下文获取,这种方式是不可行的,
void方法不定义HttpServletResponse类型的入参,Spring MVC会认为@RequestMapping注解中指定的路径就是要返回的视图name
页面上访问 http://127.0.0.1:8080/MavenSpringMvcDemo/voidMethod/demo2,接着会将
http://127.0.0.1:8080/MavenSpringMvcDemo/jsp/voidMethod/demo2.jsp 作为此次请求的响应内容,如果这个jsp文件项目中不存在则报错

例子:
Controller

@PostMapping("/appreciate")//点赞功能
public void appreciate(@RequestParam(value = "isAppreciate") Boolean isAppreciate, @RequestParam(value="blogId") Long blogId){
    Blog blog = blogService.findById(blogId);
    if (isAppreciate){//点赞  数据库appreciateNum+1
        blog.setAppreciateNum(blog.getAppreciateNum()+1);
    }else{//取消点赞    数据库appreciateNum-1
        blog.setAppreciateNum(blog.getAppreciateNum()-1);
    }
    blogService.updateAppreciateNum(blog);
}

错误
在这里插入图片描述
因为上面说的用了void方法之后会把RequestMapping的路劲当成页面返回,所以就会报template中没有找到/blogDetail/appreciate页面的错误

更改
将void方法换成String方法
因为前段的请求是ajax的post请求,所以返回一个String然后到前端console.log(data)更好
Controller

@PostMapping("/appreciate")//点赞功能
@ResponseBody
public String appreciate(@RequestParam(value = "isAppreciate") Boolean isAppreciate, @RequestParam(value="blogId") Long blogId){
    Blog blog = blogService.findById(blogId);
    if (isAppreciate){//点赞  数据库appreciateNum+1
        blog.setAppreciateNum(blog.getAppreciateNum()+1);
    }else{//取消点赞    数据库appreciateNum-1
        blog.setAppreciateNum(blog.getAppreciateNum()-1);
    }
    blogService.updateAppreciateNum(blog);
    return "更新成功!";
}

JS

function appreciate(){//点赞功能数据库appreciateNum+1
    var isAppreciate = $("#dianzan-btn").hasClass('red')?'true':'false';
    console.log(isAppreciate);
    var blogId = $("#blogId").val();
    console.log(blogId);
    var adata = {
        "isAppreciate":isAppreciate,
        "blogId":blogId
    };
    $.ajax({
        url : "/blog/blogDetail/appreciate",     //请求的url。与后端@Request Mapping注解中的值一致。   注意:/blog前缀是项目名一定要加上
        type : "post",//通过post方式上传请求
        // contentType : "application/json",//上传内容格式为json结构
        data : adata,                               //上传的参数
        async: true,                   //默认为true异步,false表示同步,异步不需要等待,同步需要等待回调方法做完
        success : function(data) {          //请求成功的回调函数
            console.log(data);
        },
        error : function(e) {           //请求失败的回调函数
            console.log(e);
        }
    })
};
<think>好的,我需要解释Filter和Controller之间的关系。首先,用户可能对这两个概念在Java Web开发中的角色不太清楚。他们可能想知道它们如何协同工作,或者各自的职责是什么。 首先,我应该回顾一下Servlet规范中的Filter和Controller(通常是Servlet或Spring MVC中的控制器)。Filter属于Servlet规范的一部分,而Controller更多是框架面的概念,比如在Spring MVC中。需要明确它们的作用域和执行顺序。 然后,要说明Filter的作用,比如请求预处理、日志记录、安全检查、编码设置等。而Controller负责处理具体的业务逻辑,生成响应内容。需要强调Filter在请求到达Controller之前和响应返回客户端之前拦截请求和响应的能力。 接下来,可能需要提到Filter链的概念,多个Filter可以按顺序处理同一个请求,最后到达Controller。这有助于用户理解流程的顺序。此外,在Spring MVC中,DispatcherServlet作为前端控制器,本身也是一个Servlet,而Filter是在DispatcherServlet之前执行的,所以用户配置的Filter会影响所有的请求处理流程。 还要考虑用户可能的误区,比如混淆Interceptor(拦截器)和Filter的区别。虽然Interceptor在Spring MVC中也有类似的功能,但它们的执行时机和作用域不同,Filter更底,属于Servlet面,而Interceptor属于Spring框架面。 可能需要举一些例子,比如使用Filter进行权限验证,如果验证不通过,直接返回403错误,而不会到达Controller。或者记录请求日志,在请求处理前后记录时间戳,计算处理时间。 另外,需要提醒用户配置Filter时的注意事项,比如在web.xml中的配置顺序,或者使用注解的方式,以及Filter的初始化参数等。在Spring Boot中,通过FilterRegistrationBean来注册Filter,控制其顺序。 最后,总结两者的关系,强调Filter作为请求处理链的一部分,为Controller提供预处理和后处理的支持,使得业务逻辑与非业务逻辑(如安全、日志)能够分离,符合单一职责原则。</think>在Java Web开发中,Filter(过滤器)和Controller(控制器)是请求处理流程中的两个关键组件,它们的关系可以通过以下分步解释来理解: --- ### **一、角色定位** 1. **Filter** - **定位**:Servlet规范定义的组件,属于**请求处理链**的中间环节 - **职责**: - 预处理请求(如权限验证、日志记录、字符编码设置) - 后处理响应(如压缩响应内容、添加统一HTTP头) - 拦截请求(可终止请求传递,直接返回响应) - **特性**: - 可配置多个Filter形成链式处理 - 独立于具体业务逻辑 2. **Controller** - **定位**:在MVC框架(如Spring MVC)中,属于**业务逻辑处理终点** - **职责**: - 解析请求参数 - 执行业务逻辑(如数据库操作) - 生成响应数据(如JSON、HTML视图) - **特性**: - 与具体业务场景强关联 - 通常通过注解(如`@Controller`)定义路由映射 --- ### **二、执行流程关系** **典型请求处理顺序**: $$ \text{客户端} \rightarrow \text{Filter链} \rightarrow \text{DispatcherServlet(前端控制器)} \rightarrow \text{Controller} \rightarrow \text{Filter链} \rightarrow \text{客户端} $$ **具体步骤**: 1. **请求进入阶段** - 所有HTTP请求首先经过配置的Filter链 - 示例场景: ```java public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { // 1. 预处理(如设置编码) req.setCharacterEncoding("UTF-8"); // 2. 放行请求到下一个Filter或目标Servlet/Controller chain.doFilter(req, res); // 3. 后处理(如记录响应时间) log.info("Response completed"); } ``` 2. **到达Controller** - 请求通过Filter链后,由前端控制器(如Spring的`DispatcherServlet`)路由到具体的Controller方法 - 示例代码: ```java @RestController public class UserController { @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { return userService.findUser(id); // 业务逻辑处理 } } ``` 3. **响应返回阶段** - Controller生成响应后,响应数据会**反向经过Filter链**(按配置的逆序) - Filter可对响应内容进行二次处理 --- ### **三、核心差异对比** | 特性 | Filter | Controller | |---------------------|---------------------------------|---------------------------------| | **所属级** | Servlet规范(底) | MVC框架(业务) | | **处理阶段** | 全局请求/响应处理 | 具体业务逻辑处理 | | **配置方式** | `web.xml`或`@WebFilter` | 注解(如`@Controller`) | | **能否终止请求** | 能(不调用`chain.doFilter()`) | 否(必须返回响应) | | **访问范围** | 所有请求(可配置URL模式) | 特定路由映射的请求 | --- ### **四、协作场景示例** #### **场景1:权限验证** ```java // Filter实现登录检查 public class AuthFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletRequest request = (HttpServletRequest) req; if (request.getSession().getAttribute("user") == null) { // 未登录则直接返回401,不进入Controller ((HttpServletResponse) res).sendError(401); return; } chain.doFilter(req, res); // 放行到Controller } } ``` #### **场景2:响应压缩** ```java // Filter对响应内容进行GZIP压缩 public class GzipFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Content-Encoding", "gzip"); chain.doFilter(req, new GzipResponseWrapper(response)); // 包装响应对象 } } ``` --- ### **五、设计意义** 1. **关注点分离** - Filter处理**横切关注点**(Cross-Cutting Concerns,如日志、安全) - Controller专注**业务逻辑** 2. **可复用性** - Filter可配置到多个Controller的请求路径 3. **灵活性** - 通过Filter链顺序控制处理优先级 --- ### **六、常见误区** - **Filter与Interceptor的区别** - Filter属于Servlet规范,Interceptor是Spring MVC的组件 - Filter更底,可处理静态资源请求;Interceptor仅作用于Controller方法 - **过度使用Filter** - 业务相关逻辑(如参数校验)应放在Controller或Service --- **总结**:Filter是请求处理的“守门人”,负责全局性预处理和后处理;Controller是业务逻辑的“执行者”,两者通过链式协作实现职责分离,共同构建完整的Web请求处理流程。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值