for example
if i have used findByEmail my url will look something like this
http://localhost:8080/api/carts/search/findByEmail?email=helloworld#gmail.com
how will the URL for delete request look if i have deleteByEmail in JPA repository
this is how my JPA looks like
public interface CartRepository extends JpaRepository<Cart, Integer> {
#Transactional
#RestResource(exported = true)
List<Cart> deleteByEmail(String email);
}
You can have a rest API as http://localhost:8080/api/carts/email/{emailId} with emailId in PathVariable HttpMethod as DELETE. Inside the service method, you search by emailId and then Delete it using the ID.
You need to create a controller method with the appropriate mapping. You can define any URL you want, I used /api/carts/{email}. Make sure to send a HTTP DELETE request.
#RestController
public class CartController {
private final CartRepository cartRepository;
#Autowired
public CartController (CartRepository cartRepository) {
this.cartRepository = cartRepository;
}
#DeleteMapping("/api/carts/{email}")
public void deleteCart(#PathVariable String email) {
cartRepository.deleteByEmail(email);
}
}
If you prefer to solve this with a request param, change the deleteCart method as shown below:
#DeleteMapping("/api/carts")
public void deleteCart(#RequestParam String email) {
cartRepository.deleteByEmail(email);
}
Related
I am using Spring Hateoas 1.5.2 and I have a scenario where I cannot produce a Link.
#RestController
#RequestMapping("${unexisting.property.controller:/spel-defined-url}")
public class SpelDefinedController {
#AllArgsConstructor
#Data
private static class ExampleDto {
private String test;
}
#GetMapping(value = "${unexisting.property.controller.documentation:/another-spel-persons/{id}}", produces = "application/json")
public EntityModel<ExampleDto> findOne(#PathVariable Long id) {
// Creation of the self link"self" link, i.e. this method.
Link findOneLink = linkTo(methodOn(SpelDefinedController.class).findOne(id)).withSelfRel();
// We return
return EntityModel.of(new ExampleDto("test"), findOneLink);
}
}
The line of code that fails is this one
Link findOneLink = linkTo(methodOn(SpelDefinedController.class).findOne(id)).withSelfRel();
I think the issue comes with the fact that I am using SPEL inside the #Controller or the #GetMapping and these SPELs are not resolved by the linkTo.
Or I am doing something wrong. Any help to understand is appreciated.
Actually, my project in Spring send values from the database via console, like this:
Console image, but I want to send this values via JSON like a rest API, but I don't know how to change that.
{
"depositarios": {
"correo": "correo",
"nombre": "nombre",
"numTel": "numTel",
"pApellido": "pApellido",
"SApellido": "sAellido"
}
}
this is my main class:
#SpringBootApplication
#ComponentScan("com.abner.springpostgresql.service.impl, com.abner.springpostgresql.dao.imp")
public class SpringPostgresqlApplication {
public static void main(String[] args) {
ApplicationContext context= SpringApplication.run(SpringPostgresqlApplication.class, args);
depoService depoService =context.getBean(depoService.class);
depoService.loadAllDepo();
}
}
this is my entired project source https://github.com/abnercoronado/restpostgresql
You have to create a RestController using the #RestController annotation like this:
#RestController
public class MyRestController {
#RequestMapping(value = "/personas", method = RequestMethod.GET)
public List<Persona> listaPersonas() {
// This is just a sample. Here you could bring your data form your db
List<Persona> lista = new ArrayList<Persona>();
Persona p = new Persona();
p.setNombre("angel");
p.setEdad(20);
lista.add(p);
return lista;
}
}
The value of the #RequestMapping annotation ("/personas" in this example) will be the endpoint. So when you access to the endpoint http://localhost:8080/personas (asuming that your app is running on http://localhost:8080) then you will get your data as json.
Here is an example of how to do it.
Here is another example (en espaƱol) that could help you.
You can use ObjectMapper to convert your pojo or object to JSON String and send where ever you wanted using thier API or anything.
Or you can create Rest Method and Access the API would return you the Json Value.
#RestController
public class MyRestController {
#RequestMapping(value = "/depo", method = RequestMethod.GET)
public List<?> getDepo() {
ApplicationContext context= SpringApplication.run(SpringPostgresqlApplication.class, args);
depoService depoService =context.getBean(depoService.class);
List<?> lista = depoService.loadAllDepo();
return lista;
}
Another way of doing.
#RestController
public class MyRestController {
#RequestMapping(value = "/depo", method = RequestMethod.GET)
public List<Depo> getDepo() {
ApplicationContext context= SpringApplication.run(SpringPostgresqlApplication.class, args);
depoService depoService =context.getBean(depoService.class);
List<Depo> lista = depoService.loadAllDepo();
return lista;
}
Once you start your server, you can run this by doing localhost:8080/depo. you can also return XML.
I need to write a test case for constructor of the following class, where there is a void method I need to mock and verify .How to verify that createToken is get called using powermockito ?
public class Mytest{
private Static string token;
public Mytest(){
if (token == null){
createToken();
}else
{
Log.error("log message");
}
}
private void createToken() {
// logic to create token
}
}
Test class
public class TestMytest{
//set token to null
PowerMockito.spy(Mytest.class);
final String token = null;
Whitebox.setInternalState(Mytest.class,
"token", token);
//supress the createToken() method
MemberModifier.suppress(MemberMatcher.method(
Mytest.class, "createToken"));
new Mytest();
**//verify(??????????)**
}
Why do you want to do this verification? What you in fact want to do is to check whether the token has been set? BTW Why is it even static? You want to have each instance of the class the same value of the token?
Either add a getter for the token field or make it package private.
public class Mytest{
final String token;
public Mytest(){
createToken();
}
private void createToken() {
// logic to create token
}
}
and you can test it like this (I don't remember if Matchers have this method but you get the idea):
assertThat(new Mytest().token, Matchers.notNull())
I'm trying to send a complex data type from one process to another using ASP.net MVC. For some reason the receiving end always receives blank (zero/default) data.
My sending side:
static void SendResult(ReportResultModel result)
{
//result contains valid data at this point
string portalRootPath = ConfigurationManager.AppSettings["webHost"];
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(portalRootPath);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage resp = client.PostAsJsonAsync("Reports/MetricEngineReport/MetricResultUpdate", result).Result;
if (!resp.IsSuccessStatusCode) {
//I've confirmed this isn't happening by putting a breakpoint in here.
}
}
My receiving side, in a different class, running in a different process on my local machine:
public class MetricEngineReportController : Controller
{
...
[HttpPost]
public void MetricResultUpdate(ReportResultModel result)
{
//this does get called, but
//all the guids in result are zero here :(
}
...
}
My model is a bit complicated:
[Serializable]
public class ReportResultModel
{
public ReportID reportID {get;set;}
public List<MetricResultModel> Results { get; set; }
}
[Serializable]
public class MetricResultModel
{
public Guid MetricGuid { get; set; }
public int Value { get; set; }
public MetricResultModel(MetricResultModel other)
{
MetricGuid = other.MetricGuid;
Value = other.Value;
}
public MetricResultModel(Guid MetricGuid, int Value)
{
this.MetricGuid = MetricGuid;
this.Value = Value;
}
}
[Serializable]
public struct ReportID
{
public Guid _topologyGuid;
public Guid _matchGuid;
}
Any idea why the data's not arriving?
Any help would be much appreciated...
P.S. For some reason I can't seem to catch the http POST message on fiddler, not sure why that is.
Try using "[FromBody]" parameter in Controller's Action. As you post data is passed to body not in url.
[HttpPost]
public void MetricResultUpdate([FromBody] ReportResultModel result)
{
//this does get called, but
//all the guids in result are zero here :(
}
The problem was twofold:
I needed to specify the type in my JSON post like this:
HttpResponseMessage resp = client.PostAsJsonAsync<MetricResultModel>("Reports/MetricEngineReport/MetricResultUpdate", result.Results[0]).Result;
The components of my model did not have default constructors, which is necessary for the JSON deserialization on the receiving end.
I just had the same problem. It seems that the content-length header is set to 0 when using the default PostAsJsonAsync extension method, which causes the server to ignore the request body.
My solution was to install the System.Net.Http.Json nuget package that uses the new System.Text.Json serializer.
When you add using System.Net.Http.Json;, you should be able to use the new extension method PostAsJsonAsync that works (sets the content-length header) properly.
namespace System.Net.Http.Json
{
public static class HttpClientJsonExtensions
{
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken)
{
return client.PostAsJsonAsync(requestUri, value, null, cancellationToken);
}
}
}
I have several controllers that return the same generic Response object with #ResponseBody annotation, like this:
#RequestMapping(value = "/status", method = RequestMethod.GET)
#Transactional(readOnly = true)
public #ResponseBody Response<StatusVM> status()
I need to perform an operation on every controller, after the Response is returned. This operation will enrich the Response object with new data.
I don't want to duplicate code, so I need a single point of intervention. I thought I could do this with Interceptors, however, according to the docs http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor this does not work well with #ResponseBody:
Note that the postHandle method of HandlerInterceptor is not always ideally suited for use with #ResponseBody and ResponseEntity methods. In such cases an HttpMessageConverter writes to and commits the response before postHandle is called which makes it impossible to change the response, for example to add a header. Instead an application can implement ResponseBodyAdvice and either declare it as an #ControllerAdvice bean or configure it directly on RequestMappingHandlerAdapter.
I haven't been able to find an example of this tecnique, could anybody help me?
As an alternative I could work with aspects, but then I'd need to annotate every controller, which is something I'd like to avoid.
In the end I implemented ResponseBodyAdvice like this:
#ControllerAdvice
public class StatusAdvice implements ResponseBodyAdvice<Response<?>> {
#Override
public boolean supports(MethodParameter returnType,
Class<? extends HttpMessageConverter<?>> converterType) {
if (returnTypeIsReponseVM(returnType)&&responseConverterIsJackson2(converterType)){
return true;
}
return false;
}
....
#Override
public Response<?> beforeBodyWrite(Response<?> body, MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
....
return body;
}
}
So it was easier then expected.