【问题标题】:Return only string message from Spring MVC 3 Controller仅从 Spring MVC 3 控制器返回字符串消息
【发布时间】:2011-12-02 03:19:44
【问题描述】:

谁能告诉我如何从控制器返回字符串消息?

如果我只是从控制器方法返回一个字符串,那么 spring mvc 将其视为 jsp 视图名称。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:
    @Controller
    public class HelloController {
        @RequestMapping(value = "/", method = RequestMethod.GET)
        ResponseEntity<String> sayHello() {
            return ResponseEntity.ok("Hello");
        }
    }
    

    【讨论】:

      【解决方案2】:

      有两种可能的解决方案

      1. 使用@Controller@ResponseBody,将HTML页面和不同功能的字符串消息结合起来

        @Controller
        @RequestMapping({ "/user/registration"})
        public class RegistrationController {    
        @GetMapping
         public String showRegistrationForm(Model model) {
             model.addAttribute("user", new UserDto());
             return "registration"; //Returns the registration.html
         }
        
         @PostMapping
         @ResponseBody
         public String registerUserAccount(@Valid final UserDto accountDto, final HttpServletRequest request) {
             LOGGER.debug("Registering user account with information: {}", accountDto);
             return "Successfully registered" // Returns the string
         }
        
      2. 使用@RestController 返回字符串消息。在这种情况下,你不能有返回 HTML 页面的函数。

         @RestController
         @RequestMapping({ "/user/registration"})
         public class RegistrationController {
        
         @PostMapping
             public String registerUserAccount(@Valid @RequestBody final UserDto accountDto, final HttpServletRequest request) {
                 LOGGER.debug("Registering user account with information: {}", accountDto);
                 return "Successfully registered" // Returns the string
             }
        

      【讨论】:

        【解决方案3】:
        @ResponseBody
        @RequestMapping(value="/get-text", produces="text/plain")
        public String myMethod() {
             return "Response!";
        }
        
        • 你看到@ResponseBody了吗?

        这说明该方法返回一些文本而不是解释 它作为一个视图等。

        • 你看到produces="text/plain"了吗?

        这只是一个好习惯,因为它告诉我们将从 方法:)

        【讨论】:

          【解决方案4】:

          最简单的解决方案:

          只是加引号,我真的不知道为什么当响应类型定义为application / json时它没有被Spring boot自动实现,但是它很好用。

          @PostMapping("/create")
          public String foo()
          {
              String result = "something"
              return "\"" + result + "\"";
          }
          

          【讨论】:

            【解决方案5】:

            在 Spring 4 中,如果您的 Controller 使用 @RestController 而不是 @Controller 注释,则不需要 @ResponseBody 注释。

            代码是

            @RestController
            public class FooController {
            
               @RequestMapping(value="/controller", method=GET)
               public String foo() {
                  return "Response!";
               }
            
            }
            

            您可以找到 @RestController here 的 Javadoc

            【讨论】:

            • 谢谢,这帮助我发现我需要使用 \@Controller 而不是 \@RestController 才能返回视图,而不是字符串。
            • @khriskooper 很高兴听到它:)
            【解决方案6】:

            虽然@Tomasz 是绝对正确的,但还有另一种方法:

            @RequestMapping(value="/controller", method=GET)
            public void foo(HttpServletResponse res) {
                try {       
                    PrintWriter out = res.getWriter();
                    out.println("Hello, world!");
                    out.close();
                } catch (IOException ex) { 
                    ...
                }
            }
            

            但第一种方法更可取。如果要返回自定义内容类型的响应或返回二进制类型(文件等),可以使用此方法;

            【讨论】:

            • 只是提醒一下,但您甚至不需要为此做出响应。
            • 表示第二点,关于需要设置自定义内容类型或返回二进制类型,您仍然可以使用 ResponseEntity 来实现这些方式。
            【解决方案7】:

            要将String 输出为text/plain,请使用:

            @RequestMapping(value="/foo", method=RequestMethod.GET, produces="text/plain")
            @ResponseBody
            public String foo() {
                return "bar";
            }
            

            【讨论】:

            • 这对我不起作用。在返回 String 对象之前,我必须获取响应对象并显式设置内容类型。
            【解决方案8】:

            怎么样:

            PrintWriter out = response.getWriter();
            out.println("THE_STRING_TO_SEND_AS_RESPONSE");
            return null;
            

            这很适合我。

            【讨论】:

              【解决方案9】:

              这只是为以后可能会发现此问题的人提供的说明,但您不必拉入响应即可更改内容类型。下面是一个例子:

              @RequestMapping(method = RequestMethod.GET, value="/controller")
              public ResponseEntity<byte[]> displayUploadedFile()
              {
                HttpHeaders headers = new HttpHeaders();
                String disposition = INLINE;
                String fileName = "";
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
              
                //Load your attachment here
              
                if (Arrays.equals(Constants.HEADER_BYTES_PDF, contentBytes)) {
                  headers.setContentType(MediaType.valueOf("application/pdf"));
                  fileName += ".pdf";
                }
              
                if (Arrays.equals(Constants.HEADER_BYTES_TIFF_BIG_ENDIAN, contentBytes)
                    || Arrays.equals(Constantsr.HEADER_BYTES_TIFF_LITTLE_ENDIAN, contentBytes)) {
                  headers.setContentType(MediaType.valueOf("image/tiff"));
                  fileName += ".tif";
                }
              
                if (Arrays.equals(Constants.HEADER_BYTES_JPEG, contentBytes)) {
                  headers.setContentType(MediaType.IMAGE_JPEG);
                  fileName += ".jpg";
                }
              
                //Handle other types if necessary
              
                headers.add("Content-Disposition", , disposition + ";filename=" + fileName);
                return new ResponseEntity<byte[]>(uploadedBytes, headers, HttpStatus.OK);
              }
              

              【讨论】:

                【解决方案10】:

                在控制器中用@ResponseBody注释你的方法:

                @RequestMapping(value="/controller", method=GET)
                @ResponseBody
                public String foo() {
                    return "Response!";
                }
                

                发件人:15.3.2.6 Mapping the response body with the @ResponseBody annotation

                @ResponseBody 注释 [...] 可以放在方法上,并指示返回类型应直接写入 HTTP 响应正文(而不是放在模型中,或解释为视图名称)。

                【讨论】:

                • 为了更清楚,我会添加 produces="text/plain @RequestMapping(value="/controller", method=GET, produces="text/plain")
                • 真正的答案总是在 cmets 中。