Den*_*sMP 3 rest json spring-boot angular
我有一个 springboot REST 控制器,其中包含所示的 PATCH 和 PUT 请求方法。由于某种原因,@RequestBody“公司”的字段/属性作为空值出现。我缺少什么?
\n\n我在前端使用 angular8,它正在执行 PATCH 调用。
\n\n我尝试过其他一些帖子的建议,但没有运气。如果这是一个重复的问题,请指出我的答案。
\n\nSpring Tool Suite 4 \nRun Code Online (Sandbox Code Playgroud)\n\n版本:4.1.0.RELEASE\n内部版本号:201812201347
\n\n版权所有 (c) 2007 - 2018 Pivotal, Inc.\n保留所有权利。访问http://spring.io/tools4
\n\n我正在使用 pgAdmin 4.12 作为 postgres。
\n\n这是我从 Angular 发出的电话:
\n\n this.companyService.patch$(this.currentId, this.appMenu.currentObject).subscribe(selectedCompany => {this.appMenu.currentObject = selectedCompany});\nRun Code Online (Sandbox Code Playgroud)\n\n这是如上所述调用的角度服务:
\n\n import { Injectable } from \'@angular/core\';\nimport { HttpClient } from \'@angular/common/http\';\nimport { Observable, BehaviorSubject } from \'rxjs\';\nimport { Company } from \'../models/company.model\';\n\n@Injectable({\n providedIn: \'root\'\n})\nexport class CompanyService {\n private url: string;\n\n constructor(private http: HttpClient) {\n this.url = "http://localhost:8080/niche/company";\n }\n\n getOne$ = (companyId: number): Observable<Company> => this.http.get<Company>(`${this.url}/${companyId}`);\n\n get$ = (): Observable<Company[]> => this.http.get<Company[]>(this.url);\n\n post$ = (company: Company): Observable<Company> => this.http.post<Company>(this.url, { company });\n\n patch$ = (companyId: number, company: Company): Observable<Company> => this.http.patch<Company>(`${this.url}/${companyId}`, { company });\n\n delete$ = (companyId: number): Observable<Company> => this.http.delete<Company>(`${this.url}/${companyId}`);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n从 Angular 前端请求有效负载:
\n\n {company: {createdBy: "denis", createdDate: "2019-04-14T04:00:00.000+0000", updatedBy: "denis",\xe2\x80\xa6}}\ncompany: {createdBy: "denis", createdDate: "2019-04-14T04:00:00.000+0000", updatedBy: "denis",\xe2\x80\xa6}\ncompanyName: "Bull Winkle"\ncreatedBy: "denis"\ncreatedDate: "2019-04-14T04:00:00.000+0000"\nemail: "bullwinkle@mail.com"\nid: 2\nnotes: "test"\nphone: "999999999"\nproducts: []\nupdatedBy: "denis"\nupdatedDate: "2019-05-14T04:00:00.000+0000"\nwebSite: "bullwilkle.com"\nRun Code Online (Sandbox Code Playgroud)\n\n这是实际的 JSON:
\n\n{"company":{"createdBy":"denis","createdDate":"2019-04-14T04:00:00.000+0000","updatedBy":"denis","updatedDate":"2019-05-14T04:00:00.000+0000","id":2,"email":"bullwinkle@mail.com","companyName":"Bull Winkle","webSite":"bullwilkle.com","phone":"999999999","notes":"test","products":[]}}\nRun Code Online (Sandbox Code Playgroud)\n\nspringboot后端控制器:
\n\n /**\n * \n */\npackage com.ebusiness.niche.controller;\n\nimport java.util.List;\nimport java.util.Optional;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.CrossOrigin;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestBody;\n\nimport com.ebusiness.niche.entity.Company;\nimport com.ebusiness.niche.service.CompanyService;\n//import com.sun.istack.internal.logging.Logger;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * @author denisputnam\n *\n */\n@RestController\n@RequestMapping( value = "/niche" )\npublic class CompanyController {\n private final Logger log = LoggerFactory.getLogger(this.getClass());\n\n @Autowired\n private CompanyService companyService;\n\n @ResponseBody\n @RequestMapping(value = {"/company"}, method = { RequestMethod.GET })\n @CrossOrigin(origins = "http://localhost:4200")\n public ResponseEntity<List<Company>> getCompanys() {\n log.info("getCompanys(): Called...");\n\n List<Company> companyList = null;\n\n companyList = this.companyService.findAll();\n\n if( companyList == null || companyList.isEmpty() ) {\n log.info("getCompanys(): returned a null or empty list.");\n ResponseEntity<List<Company>> rVal = new ResponseEntity<List<Company>>(companyList, HttpStatus.NO_CONTENT);\n return rVal;\n }\n return new ResponseEntity<List<Company>>(companyList, HttpStatus.OK); \n }\n\n @ResponseBody\n @RequestMapping(value = {"/company/{id}"}, method = { RequestMethod.GET })\n @CrossOrigin(origins = "http://localhost:4200")\n public ResponseEntity<Company> getCompany(@PathVariable("id") Long id) {\n log.info("getCompany(): Called...");\n log.info("id=" + id);\n\n// List<Company> companyList = null;\n Optional<Company> optcompany = null;\n Company company = null;\n\n optcompany = this.companyService.findById(id);\n\n if( optcompany == null ) {\n log.info("getCompany(): returned a null.");\n ResponseEntity<Company> rVal = new ResponseEntity<Company>(company, HttpStatus.NO_CONTENT);\n return rVal;\n } else {\n company = optcompany.get();\n }\n return new ResponseEntity<Company>(company, HttpStatus.OK); \n }\n\n @ResponseBody\n// @RequestMapping(value = {"/company/{id}"}, headers = {\n// "content-type=application/json" }, consumes = MediaType.APPLICATION_JSON_VALUE, method = { RequestMethod.PATCH, RequestMethod.PUT, RequestMethod.POST })\n @RequestMapping(value = {"/company/{id}"}, method = { RequestMethod.PATCH, RequestMethod.PUT })\n @CrossOrigin(origins = {"http://localhost:4200"})\n public ResponseEntity<Company> updateCompany(@PathVariable("id") Long id, @RequestBody Company company) {\n log.info("updateCompany(): Called...");\n log.info("id=" + id);\n\n Optional<Company> currentCompany = this.companyService.findById(id);\n Company dbCompany = null;\n\n if( currentCompany == null ) {\n log.error("Unable to update. The company with id {} not found.", id);\n ResponseEntity<Company> rVal = new ResponseEntity<Company>(company, HttpStatus.NO_CONTENT);\n return rVal;\n }\n\n dbCompany = currentCompany.get();\n dbCompany.setCompanyName(company.getCompanyName());\n dbCompany.setEmail(company.getEmail());\n dbCompany.setNotes(company.getNotes());\n dbCompany.setPhone(company.getPhone());\n dbCompany.setWebSite(company.getWebSite());\n\n this.companyService.update(dbCompany);\n\n return new ResponseEntity<Company>(dbCompany, HttpStatus.OK); \n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\nspringboot后端实体bean:
\n\n /**\n * \n */\npackage com.ebusiness.niche.entity;\n\nimport java.io.Serializable;\nimport java.util.Set;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.GeneratedValue;\nimport javax.persistence.Id;\nimport javax.persistence.ManyToMany;\nimport javax.persistence.Table;\nimport javax.persistence.UniqueConstraint;\nimport javax.validation.constraints.NotNull;\n\n/**\n * @author denisputnam\n *\n */\n@Entity\n@Table(\n uniqueConstraints = {\n @UniqueConstraint(columnNames = {"email"})\n }\n)\npublic class Company extends History implements Serializable{\n\n /**\n * \n */\n private static final long serialVersionUID = 1329304564033025946L;\n\n @Id\n @GeneratedValue\n private Long id;\n\n @Column\n @NotNull\n private String email;\n\n @Column\n @NotNull\n private String companyName;\n\n @Column\n @NotNull\n private String webSite;\n\n @Column\n @NotNull\n private String phone;\n\n @Column(length=4096)\n private String notes;\n\n @ManyToMany(mappedBy="companys")\n Set<Product> products;\n\n public String getNotes() {\n return notes;\n }\n\n public void setNotes(String notes) {\n this.notes = notes;\n }\n\n public Long getId() {\n return id;\n }\n\n public void setId(Long id) {\n this.id = id;\n }\n\n public String getEmail() {\n return email;\n }\n\n public void setEmail(String email) {\n this.email = email;\n }\n\n public String getCompanyName() {\n return companyName;\n }\n\n public void setCompanyName(String companyName) {\n this.companyName = companyName;\n }\n\n public String getWebSite() {\n return webSite;\n }\n\n public void setWebSite(String webSite) {\n this.webSite = webSite;\n }\n\n public String getPhone() {\n return phone;\n }\n\n public void setPhone(String phone) {\n this.phone = phone;\n }\n\n public Set<Product> getProducts() {\n return products;\n }\n\n public void setProducts(Set<Product> products) {\n this.products = products;\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这个History基类实体bean:
\n\n /**\n * \n */\npackage com.ebusiness.niche.entity;\n\nimport java.io.Serializable;\nimport java.util.Date;\n\nimport javax.persistence.Column;\nimport javax.persistence.MappedSuperclass;\nimport javax.validation.constraints.NotNull;\n\n/**\n * @author denisputnam\n *\n */\n//@Entity\n@MappedSuperclass\npublic class History implements Serializable {\n /**\n * \n */\n private static final long serialVersionUID = -1136283585074348099L;\n private String createdBy;\n @Column(nullable = false)\n @NotNull\n private Date createdDate = new Date();\n private String updatedBy;\n private Date updatedDate;\n /**\n * @return the createdBy\n */\n public String getCreatedBy() {\n return createdBy;\n }\n /**\n * @param createdBy the createdBy to set\n */\n public void setCreatedBy(String createdBy) {\n this.createdBy = createdBy;\n }\n /**\n * @return the createdDate\n */\n public Date getCreatedDate() {\n return createdDate;\n }\n /**\n * @param createdDate the createdDate to set\n */\n public void setCreatedDate(Date createdDate) {\n this.createdDate = createdDate;\n }\n /**\n * @return the updatedBy\n */\n public String getUpdatedBy() {\n return updatedBy;\n }\n /**\n * @param updatedBy the updatedBy to set\n */\n public void setUpdatedBy(String updatedBy) {\n this.updatedBy = updatedBy;\n }\n /**\n * @return the updatedDate\n */\n public Date getUpdatedDate() {\n return updatedDate;\n }\n /**\n * @param updatedDate the updatedDate to set\n */\n public void setUpdatedDate(Date updatedDate) {\n this.updatedDate = updatedDate;\n }\n\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我编辑了此内容以添加控制台日志中的 TRACE 输出。我还简化了 Company 实体,使其不包含任何日期或与其他实体的任何其他关系,因此现在仅传递字符串。
\n\n这是跟踪输出:
\n\n 2019-09-18 15:52:19.591 TRACE 47732 --- [nio-8080-exec-1] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources\n2019-09-18 15:52:19.591 TRACE 47732 --- [nio-8080-exec-1] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#afterCompletionCallback(true)\n2019-09-18 15:52:19.591 TRACE 47732 --- [nio-8080-exec-1] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsAfterTransactionCompletion(3)\n2019-09-18 15:52:19.591 TRACE 47732 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : SessionImpl#afterTransactionCompletion(successful=true, delayed=false)\n2019-09-18 15:52:19.594 DEBUG 47732 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using \'application/json\', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]\n2019-09-18 15:52:19.594 TRACE 47732 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [[com.ebusiness.niche.entity.Company@ddb52f3, com.ebusiness.niche.entity.Company@73d5674e]]\n2019-09-18 15:52:19.619 TRACE 47732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No view rendering, null ModelAndView returned.\n2019-09-18 15:52:19.619 TRACE 47732 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Closing session [f1652eeb-71a2-4776-8d94-9573336d60f3]\n2019-09-18 15:52:19.619 TRACE 47732 --- [nio-8080-exec-1] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@6effa4c8]\n2019-09-18 15:52:19.619 TRACE 47732 --- [nio-8080-exec-1] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources\n2019-09-18 15:52:19.619 TRACE 47732 --- [nio-8080-exec-1] o.h.r.j.i.LogicalConnectionManagedImpl : Closing logical connection\n2019-09-18 15:52:19.620 TRACE 47732 --- [nio-8080-exec-1] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources\n2019-09-18 15:52:19.620 TRACE 47732 --- [nio-8080-exec-1] o.h.r.j.i.LogicalConnectionManagedImpl : Logical connection closed\n2019-09-18 15:52:19.620 DEBUG 47732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK, headers={masked}\n2019-09-18 15:52:31.192 TRACE 47732 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<com.ebusiness.niche.entity.Company> com.ebusiness.niche.controller.CompanyController.updateCompany(java.lang.Long,com.ebusiness.niche.entity.Company)\n2019-09-18 15:52:31.264 TRACE 47732 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<com.ebusiness.niche.entity.Company> com.ebusiness.niche.controller.CompanyController.updateCompany(java.lang.Long,com.ebusiness.niche.entity.Company)\n2019-09-18 15:52:31.266 TRACE 47732 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : PUT "/niche/company/2", parameters={}, headers={masked} in DispatcherServlet \'dispatcherServlet\'\n2019-09-18 15:52:31.267 TRACE 47732 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<com.ebusiness.niche.entity.Company> com.ebusiness.niche.controller.CompanyController.updateCompany(java.lang.Long,com.ebusiness.niche.entity.Company)\n2019-09-18 15:52:31.268 TRACE 47732 --- [nio-8080-exec-3] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session. tenant=null, owner=null\n2019-09-18 15:52:31.268 TRACE 47732 --- [nio-8080-exec-3] org.hibernate.internal.SessionImpl : Opened Session [740dabea-2970-4491-8ff7-d373afc649f6] at timestamp: 1568836351268\n2019-09-18 15:52:31.268 TRACE 47732 --- [nio-8080-exec-3] o.s.web.cors.DefaultCorsProcessor : Skip: response already contains "Access-Control-Allow-Origin"\n2019-09-18 15:52:31.312 TRACE 47732 --- [nio-8080-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [com.ebusiness.niche.entity.Company@46388186]\n2019-09-18 15:52:31.320 TRACE 47732 --- [nio-8080-exec-3] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [2, com.ebusiness.niche.entity.Company@46388186]\nRun Code Online (Sandbox Code Playgroud)\n
好的,这个问题是因为 fromFront End application正在将 JSON 正文作为嵌套公司的 JSON 对象发送。{ company }
patch$ = (companyId: number, company: Company): Observable<Company>
=> this.http.patch<Company>(`${this.url}/${companyId}`, { company });
Run Code Online (Sandbox Code Playgroud)
然后,当请求到达Back End application字段值时null,因为它是company. 这是通过删除括号来修复的,{}以便将其作为company对象。
patch$ = (companyId: number, company: Company): Observable<Company>
=> this.http.patch<Company>(`${this.url}/${companyId}`, company);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11154 次 |
| 最近记录: |