在Spring中,RestController我RequestBody只需通过将相应的方法参数注释为@Valid或者进行输入验证@Validated.其他一些验证只能在对传入数据进行一些处理后才能执行.我的问题是,我应该使用什么类型的异常,以便它类似于@Valid注释抛出的异常,以及如何从验证结果中构造此异常.这是一个例子:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createOrder(@RequestBody @Validated(InputChecks.class) Order order) {
// Some processing of the Order goes here
Set<ConstraintViolation<Order>> violations = validator.validate(order, FinalChecks.class);
// What to do now with the validation errors?
orders.put(order);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest().path("/" + order.getId()).build().toUri());
return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
}
Run Code Online (Sandbox Code Playgroud) 我正在使用JPARespository我的所有CRUD操作.最近我想实现排序,所以我继续Pagable.
问题是,我希望存储库方法返回List对象,我在服务层中使用它们.
我怎样才能实现这一点,有没有办法将这些Page对象转换为List?
我在 spring boot 应用程序中得到了以下 @RestController :
@Data
@RestController
public class Hello {
@Autowired
private ResturantExpensesRepo repo;
@RequestMapping(value = "/expenses/restaurants",method = RequestMethod.POST,consumes =MediaType.APPLICATION_JSON_VALUE ,
headers = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public void hello(@RequestBody ResturantExpenseDto dto)
{
Logger logger = LoggerFactory.getLogger("a");
logger.info("got a request");
ResturantExpenseEntity resturantExpenseEntity = new ResturantExpenseEntity();
resturantExpenseEntity.setDate(new Date(System.currentTimeMillis()));
resturantExpenseEntity.setName(dto.getName());
resturantExpenseEntity.setExpense(dto.getExpense());
repo.save(resturantExpenseEntity);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从 restClient/RestedClient(mozila 的两个插件)发送请求时,我收到以下错误:
{ "timestamp": 1512129442019, "status": 415, "error": "Unsupported Media Type", "message": "Content type 'text/plain;charset=UTF-8' not supported", "path": " /费用/餐厅”}
这个错误指出终点不支持 Json 内容,但我确实把
消费 =MediaType.APPLICATION_JSON_VALUE
@RequestMapping注解内
我错过了什么?
我使用Spring Boot v1.2.5创建REST应用程序.上传图片时,我检查了最大文件大小,提供了以下属性:
multipart.maxFileSize= 128KB
Run Code Online (Sandbox Code Playgroud)
在application.properties中.该工具由Spring Boot本身提供.现在检查工作正常.问题是,如何处理异常并向用户返回一条他能理解的消息?
更新1 ----------
我在我的Controller中编写了一个方法,我打算使用它来处理MultipartException @ExceptionHandler.它似乎不起作用.
这是我的代码:
@ExceptionHandler(MultipartException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
public ApplicationErrorDto handleMultipartException(MultipartException exception){
ApplicationErrorDto applicationErrorDto = new ApplicationErrorDto();
applicationErrorDto.setMessage("File size exceeded");
LOGGER.error("File size exceeded",exception);
return applicationErrorDto;
}
Run Code Online (Sandbox Code Playgroud)
更新2 ----------
在@luboskrnac指出之后,我设法找到了解决方案.我们可以ResponseEntityExceptionHandler在这里处理这个特殊情况.我相信,我们也可以使用DefaultHandlerExceptionResolver,但是ResponseEntityExceptionHandler允许我们返回一个ResponseEntity,而不是前者,它将返回的方法ModelAndView.我没有尝试过.
这是我用来处理的最终代码MultipartException:
@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger LOGGER = Logger.getLogger(CustomResponseEntityExceptionHandler.class);
@ExceptionHandler(MultipartException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
@ResponseBody
public ApplicationErrorDto handleMultipartException(MultipartException exception){
ApplicationErrorDto applicationErrorDto = new …Run Code Online (Sandbox Code Playgroud) 当我有以下模型与JSR-303(验证框架)注释:
public enum Gender {
MALE, FEMALE
}
public class Profile {
private Gender gender;
@NotNull
private String name;
...
}
Run Code Online (Sandbox Code Playgroud)
以及以下JSON数据:
{ "gender":"INVALID_INPUT" }
Run Code Online (Sandbox Code Playgroud)
在我的REST控制器中,我想处理绑定错误(gender属性的无效枚举值)和验证错误(name属性不能为null).
以下控制器方法不起作用:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@Validated @RequestBody Profile profile, BindingResult result) {
...
}
Run Code Online (Sandbox Code Playgroud)
这会com.fasterxml.jackson.databind.exc.InvalidFormatException在绑定或验证发生之前产生序列化错误.
经过一番摆弄后,我想出了这个自定义代码,它可以满足我的需求:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@RequestBody Map values) throws BindException {
Profile profile = new Profile();
DataBinder binder = new DataBinder(profile);
binder.bind(new MutablePropertyValues(values));
// validator is instance of LocalValidatorFactoryBean class
binder.setValidator(validator); …Run Code Online (Sandbox Code Playgroud) validation spring spring-mvc spring-boot spring-restcontroller
我们正在使用Spring Boot创建rest api。我们的项目分为三层(存储库,服务和控制器)。
可以说我的控制器中有GetUser api,它返回UserDTO对象。
@GetMapping
public UserDTO getUser() {
return userService.getUser();
}
Run Code Online (Sandbox Code Playgroud)
是userService.getUser()返回UserDTO对象还是返回User对象并将其转换为UserDTO控制器中的对象?哪个更好的方法?
不久,域对象到DTO对象的转换应该在服务层还是控制器层进行?
我创建了一个Aspect,它执行基本的id比较,以确保用户属于创建所请求实体的同一组.我已成功将我的方面附加到@Service方法,但它在服务层上没有意义,我需要将它附加到@RestController方法.当我尝试这样做时,一切似乎都很好,但我的Aspect从未触发,日志也是静默的.
的pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
春天的背景
<context:annotation-config/>
<context:component-scan base-package="my.pkg"/>
<aop:aspectj-autoproxy/>
<aop:config proxy-target-class="true"/>
Run Code Online (Sandbox Code Playgroud)
方面
@Aspect
@Component
public class MyAspect {
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() {}
@Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
public void restController() {}
@Pointcut("args(java.security.Principal,..)")
public void principalArgPointcut() {}
@Around("(controller() || restController()) && principalArgPointcut()")
public Object validate(ProceedingJoinPoint point) throws Throwable {
doValidationBefore();
Object result = point.proceed();
doValidationAfter();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
其中"doValidationBefore()"和"doValidationAfter()"将在验证失败时抛出异常.
最后,我的RestController
@RestController
@RequestMapping("/my-path")
public class MyController {
@RequestMapping(value = "/{entityId}", method = RequestMethod.GET)
public @ResponseBody
ResponseEntity<MyEntity> getEntityDetails(Principal principal, @PathVariable("entityId") …Run Code Online (Sandbox Code Playgroud) 我有一个示例spring rest mvc应用程序,它具有以下java代码:
SampleController.java
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("sample")
public class SampleController {
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public String getBatches()//@RequestParam(name = "name", required = true) String name)
{
return "Hello ";
}
}
Run Code Online (Sandbox Code Playgroud)
的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ved</groupId>
<artifactId>platform</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>platform Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.2.1.RELEASE</spring.version>
<jackson.version>2.6.2</jackson.version>
<spring-boot.version>1.2.6.RELEASE</spring-boot.version>
<filter.name>DEV</filter.name>
<jersey.version>1.9</jersey.version>
<base.directory>${basedir}</base.directory>
</properties>
<profiles>
<profile>
<id>local</id>
<activation> …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Spring Boot定义和保护RESTful API.理想情况下,我想使用Spring Social并允许客户(网络和移动)通过Facebook登录.
什么工作
到目前为止,我设法使用一个有效的API @RestController并使用基本的Spring Security配置对其进行保护,如下所示:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/**").authenticated()
.antMatchers(HttpMethod.PUT, "/api/**").authenticated()
.antMatchers(HttpMethod.DELETE, "/api/**").authenticated()
.anyRequest().permitAll()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
Run Code Online (Sandbox Code Playgroud)
将antMatchers很可能得到改善,但我做了这样的我自己清晰现在,它工作正常.允许执行GET请求,并且所有其他请求都需要user:password在运行时发送Spring Security提供的标准.使用示例httpie:
http POST user:a70fd629-1e29-475d-aa47-6861feb6900f@localhost:8080/api/ideas/ title="My first idea"
Run Code Online (Sandbox Code Playgroud)
哪个权利凭据,它发200 OK回一个,否则一个401 Unauthorized.
春天社交
现在,我陷入困境,无法使用我的头脑来使用Spring-Social-Facebook我当前的设置并保持完全RESTful控制器.使用标准表单和重定向似乎微不足道,但我找不到任何基于REST的方法的解决方案,例如可以轻松支持Web和移动客户端.
据我了解,客户端必须处理流程,因为后端不会向/connect/facebookURL 发送任何重定向.
我按照教程访问Facebook数据,它自己工作.但是,我想避免必须拥有教程中的那些facebookConnect.html和facebookConnected.html模板.所以我不知道如何改变它.
OAuth的另一个 …
spring spring-security spring-social spring-boot spring-restcontroller
有没有办法在 Spring 5 中缓存来自 WebClient 的 Flux?我试过这个,但没有缓存任何东西。
@RestController
@SpringBootApplication
@EnableCaching
public class GatewayApplication {
@PostMapping(value ="/test", produces = "application/json")
public Flux<String> handleRequest(@RequestBody String body) {
return getHspadQuery(body);
}
@Cacheable("testCache")
private Flux<String> getData (String body) {
return WebClient.create().post()
.uri("http://myurl")
.body(BodyInserters.fromObject(body))
.retrieve().bodyToFlux(String.class).cache();
}
}
Run Code Online (Sandbox Code Playgroud)
当我提出第三个请求时,它永远不会完成。然后在随后的请求中我得到响应,但服务器抛出以下内容:
2018-04-09 12:36:23.920 ERROR 11488 --- [ctor-http-nio-4] r.ipc.netty.channel.ChannelOperations : [HttpServer] Error processing connection. Requesting close the channel
reactor.core.Exceptions$OverflowException: Could not emit buffer due to lack of requests
at reactor.core.Exceptions.failWithOverflow(Exceptions.java:215) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxBufferPredicate$BufferPredicateSubscriber.emit(FluxBufferPredicate.java:292) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxBufferPredicate$BufferPredicateSubscriber.onNextNewBuffer(FluxBufferPredicate.java:251) ~[reactor-core-3.1.5.RELEASE.jar:3.1.5.RELEASE]
at reactor.core.publisher.FluxBufferPredicate$BufferPredicateSubscriber.tryOnNext(FluxBufferPredicate.java:205) …Run Code Online (Sandbox Code Playgroud) spring ×7
java ×4
spring-boot ×4
spring-mvc ×3
validation ×2
dto ×1
exception ×1
layer ×1
maven ×1
pagination ×1
spring-4 ×1
spring-aop ×1
spring-data ×1
spring-rest ×1
spring-web ×1
utf-8 ×1