SpringMVC转发和重定向以及socket异常

本文介绍了Spring MVC中两种常用的数据交互方式:使用ModelAndView进行重定向和转发,以及通过请求分发器Dispatcher进行页面跳转。同时探讨了这两种方式的特点及限制,例如不支持@RequestBody注解的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方式1:

使用ModelAndView

1、redirect:重定向,不过不支持重定向到post方法上,只支持get方法

2、forward:转发,支持get/post

 

 

    @RequestMapping(value = "/demoForDispatcher2", method = RequestMethod.POST)
    @ApiOperation(value = "测试feign调用put方式")
    public ModelAndView demoForDispatcher2(@ModelAttribute HbasePut hbaseput, HttpServletRequest request, HttpServletResponse response) {
        //ModelAndView modelAndView = new ModelAndView("redirect:/demo/feignDemoInv3");
        ModelAndView modelAndView = new ModelAndView("forward:/demo/feignDemoInv3");
        return modelAndView;
    }

 

 

 

 

 

方式2:

 
    @RequestMapping(value = "/demoForDispatcher", method = RequestMethod.POST)
    @ApiOperation(value = "测试feign调用put方式")
    public void demoForDispatcher(@ModelAttribute HbasePut hbaseput, HttpServletRequest request, HttpServletResponse response) {
        try {
            //request.getInputStream().reset();
            request.getRequestDispatcher("/demo/feignDemoInv2").forward(request, response);

        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

 

 

 

 

 

不过不支持@requestBody,因为application/json 等是取的request.getinputstream等,使用@requestBody一定读取了流的信息。

而request.getinputstream只能读取一次,并且没有方式重置数据流的内容。而且inputstream没有实现reset方法。

 

    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

摘抄:

 

Socket异常

客户端异常

?

1

java.net.ConnectException: Connection refused: connect。

该异常发生在客户端进行new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听。出现该问题,首先检查客户端的ip和port是否写错了,如果正确则从客户端ping一下服务器看是否能ping通,如果能ping通(服务服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动。 

java.net.SocketException: Socket is closed

常的原因是己方主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。

java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)

第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。

java.net.SocketException: Broken pipe。

抛出SocketExcepton:Connect reset by peer:Socket write error后,如果再继续写数据则抛出该异常

(暂时还没有测出来)

java.net.BindException:Address already in use: JVM_Bind。

该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监听。此时用netstat –an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决这个问题。

java.net.SocketException: Socket is closed

(同客户端)

java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)

(同客户端)

java.net.SocketException: Broken pipe。

 

 

 

 

 

 

 

<think>好的,我现在需要详细介绍Spring MVC中的转发重定向。首先,我得回顾一下这两个概念的基本定义区别,然后结合Spring MVC的具体实现方式来展开。用户可能希望了解它们的使用场景、如何编码实现以及注意事项。 首先,转发(Forward)重定向(Redirect)都是用来处理页面跳转的机制,但它们的底层工作原理不同。转发是在服务器内部进行的,客户端并不知道这次跳转,而重定向则是服务器告诉客户端去请求新的URL,因此会有两次HTTP请求。 接下来,我需要回忆在Spring MVC中如何实现这两种跳转。通常,控制器方法返回的字符串如果以"forward:"或"redirect:"开头,就会触发相应的跳转。例如,返回"forward:/path"会进行转发,而返回"redirect:/path"则会重定向。 然后,要详细说明两者的区别。比如,转发时URL不会改变,而重定向会改变;转发可以访问请求域中的数据,重定向则不能,因为它是两次独立的请求。此外,重定向可能会遇到网络延迟的问题,因为需要二次请求。 还要提到使用场景。转发适合在同一个应用内部跳转,保持请求上下文;重定向适用于防止表单重复提交,或者跳转到外部站点的情况。例如,处理完表单后重定向可以避免用户刷新页面时重复提交。 另外,需要注意路径问题。在Spring MVC中,使用重定向时,如果是相对路径,可能会有上下文路径的问题,所以最好使用绝对路径。而转发通常使用相对于当前应用的路径。 可能还需要提到一些高级特性,比如Flash属性的使用,在重定向时传递数据。因为重定向时请求属性会丢失,Spring提供了RedirectAttributes来临时保存数据,通过session传递,然后在重定向后的请求中取出并清除。 还要注意编码时的常见错误,比如忘记添加"redirect:"或"forward:"前缀,或者路径写法不正确导致404错误。例如,如果应用部署在上下文路径下,重定向到"/path"可能会缺少上下文路径,应该使用RedirectView或者加上上下文路径。 最后,可以举一些简单的代码示例,说明如何在控制器方法中使用这两种跳转方式。例如,处理一个表单提交后重定向到成功页面,或者转发到一个内部视图。 需要确保内容结构清晰,分点说明,让用户能够逐步理解两者的区别使用方法。同时,注意使用中文,避免专业术语的混淆,必要时进行解释。比如,解释HTTP状态码302表示重定向,而转发是服务器内部的forward机制。 总结时,再次强调两者的关键区别适用场景,帮助用户根据实际需求选择合适的跳转方式。</think>在Spring MVC中,**转发(Forward)****重定向(Redirect)**是实现请求跳转的两种核心机制,其底层原理、使用场景及实现方式存在显著差异。以下从多个维度详细说明: --- ### 一、核心区别 | **特性** | **转发 (Forward)** | **重定向 (Redirect)** | |------------------|-------------------------------------|-----------------------------------| | **请求次数** | 1次(服务器内部跳转) | 2次(客户端重新发起请求) | | **URL变化** | 不变化 | 变化为新的URL | | **数据共享** | 共享原始请求的`request`域属性 | 不共享,需通过`RedirectAttributes`或Session传递 | | **性能** | 更高(无额外网络开销) | 较低(需二次请求) | | **适用场景** | 同一应用内跳转 | 跨应用跳转、防表单重复提交 | --- ### 二、Spring MVC实现方式 #### 1. **转发(Forward)** - **语法**:在控制器方法返回值前添加`forward:`前缀。 - **示例**: ```java @GetMapping("/forwardExample") public String forwardExample() { return "forward:/targetPath"; // 转发到/targetPath } ``` - **特点**: - 目标路径为**应用内相对路径**,无需包含上下文路径。 - 共享原始请求的所有参数属性。 #### 2. **重定向(Redirect)** - **语法**:在返回值前添加`redirect:`前缀。 - **示例**: ```java @PostMapping("/redirectExample") public String redirectExample(RedirectAttributes attributes) { attributes.addAttribute("param", "value"); // 通过URL传参 attributes.addFlashAttribute("flashParam", "tempValue"); // 通过Flash属性传参 return "redirect:/targetPath"; // 重定向到/targetPath } ``` - **特点**: - 目标路径可为**绝对路径**(如`redirect:http://external.com`)或应用内路径。 - 使用`RedirectAttributes`传递参数: - `addAttribute()`:参数通过URL拼接(暴露在地址栏)。 - `addFlashAttribute()`:参数暂存Session,**仅在下一次请求有效**(适合敏感数据)。 --- ### 三、关键使用场景 1. **转发适用场景**: - 需要保持请求上下文(如表单数据、业务处理结果)。 - 跳转到同一应用的静态资源或内部视图(如JSP、Thymeleaf模板)。 2. **重定向适用场景**: - **防止表单重复提交**(Post-Redirect-Get模式)。 - 跨应用跳转(如支付完成后跳转回商户页面)。 - 需要更新浏览器地址栏(如登录后跳转到首页)。 --- ### 四、路径处理注意事项 - **转发路径**: ```java return "forward:/WEB-INF/views/page.jsp"; // 直接访问内部资源 ``` - **重定向路径**: ```java return "redirect:/app/target"; // 应用内路径(自动添加上下文路径) return "redirect:https://example.com"; // 外部绝对路径 ``` --- ### 五、底层原理 - **转发**:通过`RequestDispatcher.forward()`实现,服务器内部将请求交给新资源处理,**响应权完全转移**。 - **重定向**:服务器返回`302`状态码(或`303`)`Location`头,**客户端自动发起新请求**。 --- ### 六、常见问题及解决方案 1. **重定向丢失数据**: - 使用`RedirectAttributes`的`addFlashAttribute()`传递临时数据。 2. **路径错误导致404**: - 应用内重定向时,路径无需包含上下文(Spring自动处理)。 - 外部路径需写完整URL。 3. **转发无法访问外部资源**: - 转发仅限服务器内部资源,外部资源必须用重定向。 --- ### 七、代码示例 ```java @Controller public class DemoController { // 转发示例 @GetMapping("/demo/forward") public String forwardDemo(Model model) { model.addAttribute("message", "Hello Forward"); return "forward:/targetPage"; // 转发到另一个控制器方法或视图 } // 重定向示例(防表单重复提交) @PostMapping("/submitForm") public String submitForm(Form form, RedirectAttributes attributes) { // 处理表单数据... attributes.addFlashAttribute("success", "提交成功!"); return "redirect:/resultPage"; // 重定向到结果页 } @GetMapping("/resultPage") public String resultPage() { return "result"; // 显示结果视图 } } ``` --- ### 总结 - **转发**:适合服务器内部跳转,保留请求数据,性能更优。 - **重定向**:解决重复提交问题,支持跨应用跳转,需注意数据传递方式。 根据实际需求选择跳转方式,合理使用`RedirectAttributes`处理参数传递。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值