Spring RESTFul 客户端——RestTemplate。有啥奇怪的,请告诉我

Posted

技术标签:

【中文标题】Spring RESTFul 客户端——RestTemplate。有啥奇怪的,请告诉我【英文标题】:Spring RESTFul Client – RestTemplate. Have weird somthing,Please let me knowSpring RESTFul 客户端——RestTemplate。有什么奇怪的,请告诉我 【发布时间】:2016-07-16 11:44:59 【问题描述】:

我正在使用 ResTemplate 在客户端中发布用户对象。但是当我使用 postForObject 方法时,会出现未解决的编译问题The method postForObject(URI, Object, Class<T>) in the type RestTemplate is not applicable for the arguments (URL, User, Class<User>)。我真的不明白???

这里的文件RestClientTest.java`

public class RestClientTest 

    public static void main(String[] args) throws IOException
//      System.out.println("Rest Response" + loadUser("quypham"));
//      URL url = new URL("http://localhost:8080/rest/user/create");
//      rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
//      rt.getMessageConverters().add(new StringHttpMessageConverter());
//      Map<String,String> vars = new HashMap<String,String>();

        RestTemplate rt = new RestTemplate();
        User user = new User();
        user.setUserName("datpham");
        user.setPassWord("12345");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR,1960);
        user.setBirthDay(calendar.getTime());
        user.setAge(12);
        String uri = new String("http://localhost:8080/rest/user/create");
        User returns = rt.postForObject(uri, user,User.class);

//      createUser(user);
        System.out.println("Rest Response" + loadUser("datpham"));
    

这里文件UserRestServiceController

@Controller
public class UserRestServiceController 
    @Autowired
    public  UserDao userDao;
    @RequestMapping(value = "/rest/user/create",method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public void addUser(@RequestBody User user)
        userDao.save(user);
    

我编辑了String uri,但遇到新的以下错误:

2016 年 3 月 29 日下午 1:57:43 org.springframework.web.client.RestTemplate handleResponseError 警告:POST 请求 “http://localhost:8080/rest/user/create”导致 400(坏 要求);在线程“main”中调用错误处理程序异常 org.springframework.web.client.HttpClientErrorException: 400 错误 要求在 org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) 在 org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:588) 在 org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:546) 在 org.springframework.web.client.RestTemplate.execute(RestTemplate.java:502) 在 org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:330) 在 edu.java.spring.service.client.RestClientTest.main(RestClientTest.java:45)

这里是User.java

@Entity
@Table(name = "brotheruser",uniqueConstraints=@UniqueConstraint(columnNames="username"))
@JsonIgnoreProperties(ignoreUnknown = true)
public class User 
//  @Enumerated(EnumType.STRING)
//  @Column(name = "gender", nullable = false)
//   
//  public Gender getGender() 
//      return gender;
//  
//  public void setGender(Gender gender) 
//      this.gender = gender;
//  
    @Id
    @Column(name = "username", unique = true, nullable = false)
    public String getUserName() 
        return userName;
    
    public void setUserName(String userName) 
        this.userName = userName;
    
    @Column(name = "password", nullable = false)
    public String getPassWord() 
        return passWord;
    
    public void setPassWord(String passWord) 
        this.passWord = passWord;
    
    @JsonSerialize(using = DateSerializer.class)
//  @JsonDeserialize(using = DateDeserializer.class)
    @Column(name = "birthday", nullable = false)
    public Date getBirthDay() 


        return birthDay;
    

    public void setBirthDay(Date birthDay) 
        this.birthDay = birthDay;
    
    @Column(name="age", nullable = false)
    public Integer getAge() 
        return age;
    
    public void setAge(Integer age) 
        this.age = age;
    
    private String userName;
    private String passWord;
    private Date birthDay;
    private Integer age;

//  private Gender gender;



【问题讨论】:

向我们展示您的用户类!,请 你为什么使用 DtaeSerializer.class - 你没有权限...日期类型会自动序列化 【参考方案1】:

好的。我现在不能给出正确的答案。我的猜测是在您的 User 类中。 问题在于 Http 400 错误,您必须在服务器端捕获详细的错误消息 - 才能知道究竟是什么!出错了。在 spring 中使用 @ControllerAdvide 定义一个全局异常处理程序(这将帮助您处理您编程的所有内容)。这并不复杂!只需将这两个类复制并粘贴到您的项目中并确保它们被执行,如果您无权访问控制台,您将在控制台或 http 日志文件中获得详细的错误输出

希望这会有所帮助..

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.*;
import java.util.ArrayList;
import java.util.List;

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler 
    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) 
        return super.handleNoHandlerFoundException(ex, headers, status, request);
    

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) 
        return super.handleExceptionInternal(ex, body, headers, status, request);
    

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) 

        List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
        List<ObjectError> globalErrors = ex.getBindingResult().getGlobalErrors();
        List<String> errors = new ArrayList<>(fieldErrors.size() + globalErrors.size());
        String error;
        for (FieldError fieldError : fieldErrors) 
            error = fieldError.getField() + ", " + fieldError.getDefaultMessage();
            errors.add(error);
        
        for (ObjectError objectError : globalErrors) 
            error = objectError.getObjectName() + ", " + objectError.getDefaultMessage();
            errors.add(error);
        
        RestResponseErrorMessage errorMessage = new RestResponseErrorMessage(errors);
        return new ResponseEntity(errorMessage, headers, status);
    

    @Override
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) 
        String unsupported = "Unsupported content type: " + ex.getContentType();
        String supported = "Supported content types: " + MediaType.toString(ex.getSupportedMediaTypes());
        RestResponseErrorMessage errorMessage = new RestResponseErrorMessage(unsupported, supported);
        return new ResponseEntity(errorMessage, headers, status);
    

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) 
        Throwable mostSpecificCause = ex.getMostSpecificCause();
        RestResponseErrorMessage errorMessage;
        if (mostSpecificCause != null) 
            String exceptionName = mostSpecificCause.getClass().getName();
            String message = mostSpecificCause.getMessage();
            errorMessage = new RestResponseErrorMessage(exceptionName, message);
         else 
            errorMessage = new RestResponseErrorMessage(ex.getMessage());
        
        return new ResponseEntity(errorMessage, headers, status);
    


import javax.xml.bind.annotation.XmlRootElement;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Created by pk on 08.03.2016.
 */
@XmlRootElement
public class RestResponseErrorMessage 


        private List<String> errors;

        public RestResponseErrorMessage() 
        

        public RestResponseErrorMessage(List<String> errors) 
            this.errors = errors;
        

        public RestResponseErrorMessage(String error) 
            this(Collections.singletonList(error));
        

        public RestResponseErrorMessage(String ... errors) 
            this(Arrays.asList(errors));
        

        public List<String> getErrors() 
            return errors;
        

        public void setErrors(List<String> errors) 
            this.errors = errors;
        
    

【讨论】:

【参考方案2】:

我认为问题在于 URL 对象。尝试创建 URI 对象或简单的字符串,如 String url = "http://localhost:8080/rest/user/create";

RestTemplate 支持 URI 或 String 作为 postForObject 方法的第一个参数

【讨论】:

我已经按照您的方式进行了编辑,这是正确的。但是现在我遇到了新的错误,你可以给出解决方案。我在帖子中发布了新错误 向我们展示您的用户类!,请 @kamokaze,我的帖子中有用户类 @DatPham 解决了一个问题后不要去编辑你的问题,你让这个答案看起来无效。如果是新问题,请发布一个新问题,描述您目前遇到的确切问题 刚才注意到的一件事,你的休息服务应该返回用户对象。公共用户 addUser(@RequestBody 用户用户) ..

以上是关于Spring RESTFul 客户端——RestTemplate。有啥奇怪的,请告诉我的主要内容,如果未能解决你的问题,请参考以下文章

通过 Spring 进行 RESTful 身份验证

spring security + oauth2 + reactjs + restful http客户端

restful风格接口和spring的运用

使用 Spring Security 在 Web 应用程序和 RESTful 服务之间共享安全上下文

如何使用 OAuth2 和社交登录保护 Spring Boot RESTful 服务

Grails 和 Spring Security & Facebook & Oauth2 - Restful 服务器