@Controller与@RestController的不同之处?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@Controller与@RestController的不同之处?相关的知识,希望对你有一定的参考价值。

Spring中@Controller和@RestController之间的区别

web开发

spring boot web开发非常的简单,其中包括常用的json输出、filters、property、log等

json 接口开发

在以前的spring 开发的时候需要我们提供json接口的时候需要做那些配置呢

    添加 jackjson 等相关jar包

    配置spring controller扫描

    对接的方法添加@ResponseBody

    就这样我们会经常由于配置错误,导致406错误等等,spring boot如何做呢,只需要类添加 @RestController 即可,默认类中的方法都会以json的格式返回

    1. Controller, RestController的共同点

    都是用来表示Spring某个类的是否可以接收HTTP请求

    2.  Controller, RestController的不同点

    @Controller标识一个Spring类是Spring MVC controller处理器

    @RestController:  a convenience annotation that does nothing more than adding the@Controller and @ResponseBodyannotations。  @RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。

    示例如下:

    @Controller  

    @ResponseBody  

    public class MyController    

    @RestController  

    public class MyRestController   

参考技术A

在springboot中,Controller, RestController是使用控制器最常用的两个注解,但是两者之间的差异你知道吗?本文就是要讲述两者之间的区别。



1. Controller, RestController的共同点

都是用来表示Spring某个类的是否可以接收HTTP请求。

2. Controller, RestController的不同点

@Controller:标识一个Spring类是Spring MVC controller处理器,@RestController:@RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。@Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模版页面。在方法上加@ResponseBody注解,也可以返回实体对象。@RestController类中的所有方法只能返回String、Object、Json等实体对象,不能跳转到模版页面。

@RestController中的方法如果想跳转页面,则用ModelAndView进行封装,如下:

@RestControllerpublic class UserController @RequestMapping(value = "/index",method = RequestMethod.GET)public String toIndex()ModelAndView mv = new ModelAndView("index");return mv;

示例如下:

@Controller@ResponseBodypublic class MyController @RestControllerpublic class MyRestController

@Controller注解源码:

package org.springframework.stereotype;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.stereotype.Component;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Controller String value() default "";

@RestController注解源码:

package org.springframework.web.bind.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ResponseBody;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Controller@ResponseBodypublic @interface RestController String value() default "";


原文来自:https://www.cnblogs.com/mr-wuxiansheng/p/7420579.html
本文地址:https://www.linuxprobe.com/controller-rest-difference.html编辑:薛鹏旭,审核员:逄增宝
Linux命令大全:https://www.linuxcool.com/


为啥将@Transactional 与@Service 一起使用而不是与@Controller 一起使用

【中文标题】为啥将@Transactional 与@Service 一起使用而不是与@Controller 一起使用【英文标题】:Why use @Transactional with @Service instead of with @Controller为什么将@Transactional 与@Service 一起使用而不是与@Controller 一起使用 【发布时间】:2013-09-01 03:06:34 【问题描述】:

我在 stack-overflow 文章中看到了很多 cmets 我发现了一些关于 @Transactional@Service@Controller 一起使用的内容

“通常情况下,应该将事务放在服务层。”

“正常情况是在服务层级别进行注释”

“认为事务属于服务层。它了解工作单元和用例。如果您将多个 DAO 注入到需要在单个事务中协同工作的服务中,这是正确的答案。” [Source]

将@transactional 与@service 层一起使用的缺点

如果我有 2 种方法,例如 saveUser() 和 saveEmail()(因为我将电子邮件存储在数据库中以便稍后发送它们 - 就像一个队列)我会在我的服务中创建一个方法 saveUserAndSendEmail(User user) 这将交易。 [Source]

这意味着我在服务层创建了许多方法,而不是一个保存通用方法,如下所示

public <T> long save(T entity) throws DataAccessException 
    Session session = sessionFactory.getCurrentSession();
    long getGenVal=(Long) session.save(entity);
    return getGenVal;

根据上面的解决方案,这意味着我们有很多方法,如以下LOL..

public &lt;T&gt; long saveAccount(T entity)....

public &lt;T&gt; long saveWithAuditLog(T entity, K entity1)....

public &lt;T&gt; long saveWithAuditLogAndEntries(T entity, K entity, M entity)....

克服这种情况

我在@Controller 中使用@Transactional 并创建一个通用保存方法并使用这个简单的保存方法保存所有实体/模型。如果任何方法保存失败,则控制器中的所有事务都成功回滚。

确保@Transactional 应与@Controller 一起使用的其他情况

在@Controller 中:

pt.save(entity1);
pt.save(entity2);
int a = 2/0;
pt.save(entity3);

万一,@Transactional on Service,前 2 个实体成功保存,但第三个不是,它不会回滚所有事务

万一,@Controller 上的@Transactional 发生异常时所有事务回滚

为什么 stack-overflow 会问,“不要在你的控制器中做事务。把它们放在你的服务层类中。”? [source]

【问题讨论】:

我认为这种情况下最好的解决方案是在controllerservice 之间创建另一个级别层。正如我所看到的,controller 只处理调用并准备变量来处理它们并对其执行逻辑。 service 处理所有数据库内容。应该在controllerservice 之间的模型可以做一些逻辑。在您的示例中,执行少量保存操作是对 data 的逻辑操作。这意味着将它们放入model 并在需要时使用transactional 扭曲model 您的saveUser()saveEmail() 方法应该在DAO 层中。然后你让你在服务层事务中的saveUserAndSendEmail(User user)方法。 【参考方案1】:

您在询问最佳实践,最佳实践是在服务层中标记 @Transactional,因为 @Controller 不应该知道 MVC 逻辑中的数据持久性。@Service 是在使用时构造的- 从分析生成的案例并了解工作单元,并且在重用方面也实现了思考:如果您从 Web 上下文切换到桌面环境(例如,或其他一些可视化前端),​​@Controller 层没有存在您没有问题,因为所有内容都封装在服务层中。@Service 是一个合约,表示层的修改不需要重写 @Service 代码。 但是 Spring 不关心你把你的事务边界放在哪里,你可以放在 @Controller 但是你的应用程序可能会更难维护。

我希望这已经足够清楚了。抱歉,如果没有;英语不是我的母语。

【讨论】:

【参考方案2】:

让其他人知道,不鼓励使用接口注释。

Spring 建议您仅使用 @Transactional 注释来注释具体类(和具体类的方法),而不是注释接口。您当然可以将@Transactional 注释放在接口(或接口方法)上,但这仅在您使用基于接口的代理时才有效。 Java 注释不是从接口继承的事实意味着,如果您使用基于类的代理 (proxy-target-class="true") 或基于编织的方面 (mode="aspectj"),则代理和编织基础架构无法识别事务设置,并且该对象不会被包装在事务代理中,这绝对是不好的。

【讨论】:

【参考方案3】:

Controller 牢牢地位于视图层,可以随时更改。该服务仍然拥有工作单元,并且无论访问哪个视图都应该正确运行。我的回答 here 仍然有效。

【讨论】:

这意味着我必须创建许多保存方法,例如saveAccount saveAccountAudit saveAccountAuditEntries ?【参考方案4】:

我创建了一个使用其他(非事务性)服务的上层服务。而且上层服务是事务性的。

@Service
public class Service1Impl implements Servcie1 
    public Object method11()...
    public Object method12()...


@Service
public class Service2Impl implements Service2 
    public method21()...


public interface Service1 
    public Object method11();
    public Object method12();


public interface Service2 
    public Object method21();


@Transactional
public interface UpperLayerService 

@Service
public class UpperLayerServiceImpl implements UpperLayerService 
    @Autowired
    private Service2 service2;
    @Autowired
    private Service3 service3;

    public Object doWork() 
        Object o1 = service1.method11();
        Object o2 = service1.method12();
        Object o3 = service2.method21();
        ....
        Object res = null;//...Any code
        return res;
    

【讨论】:

以上是关于@Controller与@RestController的不同之处?的主要内容,如果未能解决你的问题,请参考以下文章

controller与requestmapping

restController与Controller-待续

Rails current_page?与 controller.controller_name

注解@RestController与@Controller的区别

ASP.NET MVC Controller与Areas下面的Controller同名的解决办法

ASP.NET MVC Controller与Areas下面的Controller同名的解决办法