`@RestController`注解中的值是什么作用?

huangapple go评论126阅读模式
英文:

What does the value in @RestController annotation do?

问题

使用Maven创建一个简单的Spring Boot应用程序。我已经在@RestController注解中给定了一个值,但它不起作用。如果我不使用@RestController的值,它就能正常工作。我想知道为什么它不起作用,以及@RestController中的value有什么用?

http://localhost:9090/app/hello 这会产生错误

http://localhost:9090/hello 这能正常工作

@RestController("/app")@RestController注解内部,"/app"这个值的目的是什么?

附注:我知道我可以在ScraperResource类上使用@RequestMapping("/app")

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
@RestController("/app")
public class ScraperResource {
    @GetMapping("hello")
    public String testController() {
        return "Hello";
    }
}

application.properties

server.port=9090
英文:

Creating a simple Spring Boot application using Maven. I have given a value with RestController annotation, but it doesn't work. If I don't use the RestController's value, it works. I want to know, why it's not working and What's the use of value in @RestController?

http://localhost:9090/app/hello this gives error

http://localhost:9090/hello this works fine

@RestController("/app") What's the purpose of "/app" this value inside @RestController annotation?

P.S: I know, I can use @RequestMapping("/app") on ScraperResource class.

@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
@RestController("/app")
public class ScraperResource {
	@GetMapping("hello")
	public String testController() {
		return "Hello";
	}
}

application.properties

server.port=9090

答案1

得分: 7

这是因为你的 RestController 内部的 "/app" 与你的 URL 映射无关,而是与在 Spring 内部使用的**"逻辑组件"名称**有关。

如果你想为所有的控制器方法添加前缀 /app(或者干脆省略它),你应该这样做。

@RestController
@RequestMapping("/app")
public class ScraperResource {

    @GetMapping("hello")
    public String testController() {
        return "Hello";
    }
}

没有 @RestController,Spring 将不知道这个类应该处理 HTTP 调用,所以这是一个必需的注解。

英文:

That is because the "/app" inside your RestController has nothing to do with your URL mapping, but rather with a "logical component" name being used internally Spring.

You should do this instead, if you want to prefix all your controller methods with /app (or just leave it out).

@RestController
@RequestMapping("/app")
public class ScraperResource {

    @GetMapping("hello")
    public String testController() {
        return "Hello";
    }
}

Without @RestController Spring won't know that this class should handle HTTP calls, so it is a needed annotation.

答案2

得分: 2

根据与@RestController注解相关的Java文档,这是您传递给它的值的含义:

/**
	 * 该值可能指示逻辑组件名称的建议,
	 * 在自动检测到组件的情况下,将其转换为Spring bean。
	 * @return 建议的组件名称(如果有)(否则为空字符串)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

因此,它不会影响或影响您的端点可访问的URL是什么。如果您想要添加顶级映射,您可以在类级别上使用@RequestMapping("/app"),就像您提到的那样。

英文:

As per the Java Doc associated with the @RestController annotation, this is the meaning of the value that you are passing to it:

/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

As such, it does not influence or affect what URL your endpoint is accessible with. If you want to add a top-level mapping you can use the @RequestMapping("/app") on the class-level as you mentioned.

答案3

得分: 0

@Controller注解中的参数允许您为控制器命名。在存在多个相同类型的Bean的情况下,可以使用Bean的名称以及@Qualifier注解,让Spring在自动装配期间知道要注入哪个组件。

来自文档

> 当组件在扫描过程中被自动检测为其一部分时,其Bean名称由该扫描器所知的BeanNameGenerator策略生成。默认情况下,任何包含名称值的Spring构造型注解(@Component、@Repository、@Service和@Controller)都会将该名称提供给相应的Bean定义。
>
> 如果此类注解不包含名称值,或者对于任何其他检测到的组件(例如由自定义过滤器发现的组件),默认的Bean名称生成器将返回无大写字母且未经限定的类名称。

在这里阅读有关自动装配消歧义以及如何使用@Qualifier与组件名称的更多信息这里

> 默认情况下,Spring按类型解析@Autowired条目。如果容器中有多个相同类型的Bean,则框架将抛出致命异常。
>
> 要解决这个冲突,我们需要明确告诉Spring我们想要注入哪个Bean。
>
> 当存在多个相同类型的Bean时,最好使用@Qualifier来避免歧义。
>
> 请注意,@Qualifier注解的值与我们的FooFormatter实现的@Component注解中声明的名称匹配。

英文:

The parameter in the @Controller annotation allows you to name the Controller. In cases where there are multiple beans of the same type, the bean name can be used along with the @Qualifier annotation to let Spring know which component to inject during autowiring.

From the documentation:

> When a component is autodetected as part of the scanning process, its
> bean name is generated by the BeanNameGenerator strategy known to that
> scanner. By default, any Spring stereotype annotation (@Component,
> @Repository, @Service, and @Controller) that contains a name value
> thereby provides that name to the corresponding bean definition.
>
> If such an annotation contains no name value or for any other detected
> component (such as those discovered by custom filters), the default
> bean name generator returns the uncapitalized non-qualified class
> name.

Read more about autowire disambiguation, and how to use the component name with @Qualifier here.

> By default, Spring resolves @Autowired entries by type. If more than
> one bean of the same type is available in the container, the framework
> will throw a fatal exception.
>
> To resolve this conflict, we need to tell Spring explicitly which bean
> we want to inject.
>
> When there are multiple beans of the same type, it's a good idea
> to use @Qualifier to avoid ambiguity.
>
> Please note that the value of the @Qualifier annotation matches with
> the name declared in the @Component annotation of our FooFormatter
> implementation.

huangapple
  • 本文由 发表于 2020年3月16日 04:18:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/60697251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定