BindingResult alternative in Quarkus - quarkus

I am shifting from Spring Boot.I have a couple of questions:
Is there any alternative to BindingResult in Quarkus?
my method is like this:
#PUT
public Response updateCategory(#Valid CategoryDTO pCategoryDTO) {}
And the request is this:
{ "name": "packaging", "id": 8}
But pCategoryDTO doesn't receive id(Integer), it only gets the name.I don't see any errors in logs.

Do you have the Hibernate Validator Quarkus extension added?
Also is CategoryDTO in a place that is properly indexed by Jandex? (i.e. either in your app, or if it's in an external library, it needs to be indexed)
If so, you should have an exception raised if the bean is not valid.

Related

How to use spring-data-rest without href for relation

I'm migrating a legacy application from Spring-core 4 to Springboot 2.5.2.
The application is using spring-data-rest (SDR) alongside spring-data-mongodb to handle our entities.
The legacy code was overriding SDR configuration by extending the RepositoryRestMvcConfiguration and overriding the bean definition for persistentEntityJackson2Module to remove serializerModifier and deserializerModifier.
#EnableWebMvc
#EnableSpringDataWebSupport
#Configuration
class RepositoryConfiguration extends RepositoryRestMvcConfiguration {
...
...
#Bean
#Override
protected Module persistentEntityJackson2Module() {
// Remove existing Ser/DeserializerModifier because Spring data rest expect linked resources to be in href form. Our platform is not tailored for it yet
return ConverterHelper.configureSimpleModule((SimpleModule) super.persistentEntityJackson2Module())
.setDeserializerModifier(null)
.setSerializerModifier(null);
}
It was to avoid having to process DBRef as href link when posting entities, we pass the plain POJO instead of the href and we persist it manually before the entity.
Following the migration, there is no way to set the same overrided configuration but to avoid altering all our processes of creation we would like to keep passing the POJO even for DbRef.
I will add an exemple of what was working before :
We have the entity we want to persist :
public class EntityWithDbRefRelation {
....
#Valid
#CreateOnTheFly // Custom annotation to create the dbrefEntity before persisting the current entity
#DBRef
private MyDbRefEntity myDbRefEntity;
}
the DbRefEntity
public class MyDbRefEntity {
...
private String name;
}
and the JSON Post request we are doing:
POST base-api/entityWithDbRefRelations
{
...
"myDbRefEntity": {
"name": "My own dbRef entity"
}
}
In our database this request create our myDbRefEntity and then create the target entityWithDbRefRelation with a dbRef linked to the other entity.
Following the migration, the DBRef is never created because when deserializing the JSON into a PersistingEntity, the myDbRefEntity is ignored because it's expecting an href instead of a complex object.
I see 3 solutions :
Modify all our process to first create the DBRef through one request then create our entity with the link to the dbRef
Very costly as we have a lot of services creating entities through this backend
Compliant with SDR
Define our own rest mvc controllers to do operations, to ignore the SDR mapping machanism
Add AOP into the RepositoryRestMvcConfiguration around the persistentEntityJackson2Module to set le serializerModifier and deserializedModifier to null
I really prefer to avoid this solution as Springboot must have remove a way to configure it on purpose and it could break when migrating on newer version
Does anyone know a way to continue considering the property as a complex object instead of an href link except from my 3 previous points ?
Tell me if you need more information and thanks in advance for your help!

Send post request to restcontroller with url to rest repositories

I've 2 entities A and B, where A holds an attribute "b" of class B (a one to one association between A and B)
I want to make a rest call to save an instance of A entity, and passing b param as a url which gives something like that in json:
{
"id": "5",
"b": "/restapi/B/2"
}
/b/2 refers to a findById rest resource of B Repository.
When i execute this targetting rest resource save() of A Repository (usually POST request to url /restapi/A), it works just fine, spring looks for the B entity (2 in this example) by calling the rest resource of B Repository.
I want to perform the same behavior using my own rest controller, by defining a #PostMapping function inside a #RestController component.
Is it possible ?
PS: I already tested sending the above JSON with postman, and the rest api interpreet the "/restapi/B/" as String and tries to deserialize B using a string which abviously fails.
Yes, you can autowire that repository in your restcontroller and just use it from there. You might need a Transactional annotation.
Also I would suggest to take a look at the project Spring-Data-Rest. This provides you already with what you are trying to build. It is an implementation of the HATEOAS principle.
Use #RepositoryRestController in your controller class instead of #RestController

Why Spring Boot inject same HttpServletResponse object to my Controller method for different request?

I wonder why spring boot inject same response object to my controller method parameter for different request, i use it like follow:
#Controller
#Slf4j
#Profile("default")
#RequestMapping("/test")
public class TestController {
#RequestMapping("/test")
#ResponseBody
public void getDeviceImage(#RequestParam("serialNumber") String serialNumber, HttpServletResponse response) {
return balabala;
}
}
I add a breakpoint before return command, and i find that response object's address is same for different request.
I want to write some thing to response.getOutputStream(), and i found there exists previous buffered data.
HttpServletResponse can be used if you need to add some extra meta information like cookies etc. By default even if you don't specify HttpServletResponse in the arguments, in typical MVC, model is added to the newly constructed response before propagating to the view.
If you just need to return some response back, say a model or entity or a simple JSON, you don't have to manually mess the HttpServletResponse. Unless you want to dig through cookies or headers etc.,. In your code, if you don't need to care about this, you might probably not need it.
As per the API doc for HttpServletResponse:
The servlet container creates an HttpServletResponse object and passes
it as an argument to the servlet's service methods (doGet, doPost,
etc).
What you see is probably the default configurations that Spring sets up.
With #ResponseBody, the return type is directly written back to response.
https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
Finally, i find Response will been reused all the time, and Response's recycle method will been invoked for each request(org.apache.catalina.connector.Response#recycle).
But by default facade&outputStream&writer will not been cleaned, so i make system property "org.apache.catalina.connector.RECYCLE_FACADES" to be "true", after that issue disappears.

Spring 3.1.RC1 and PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE

Posted in spring forum with no response.
I have the following code snippet (from here), which is part of my pet project.
#Controller
#RequestMapping("/browse")
public class MediaBrowser {
...
#RequestMapping("/**")
public final ModelAndView listContents(final HttpServletRequest request) {
String folder = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
...
}
I access the following url:
http://localhost:8080/myapp/browse
In spring 3.0.6.RELEASE, I got the folder variable as null, which is the expected value.
In spring 3.1.RC1, the folder variable is /browse.
Is this a bug or has something changed in spring-3.1?
As skaffman said, you probably shouldn't use PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE. Take a look at How to match a Spring #RequestMapping having a #pathVariable containing "/"? for an example of using AntPathMatcher to accomplish what you are trying
This looks very much like an internal implementation detail of the framework, one that you should not be relying on.
The javadoc for PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE says:
Note: This attribute is not required to be supported by all HandlerMapping implementations. URL-based HandlerMappings will typically support it, but handlers should not necessarily expect this request attribute to be present in all scenarios.
I wouldn't be surprised if the behaviour changed slightly between 3.0 and 3.1.

Spring 3, ReST, #ResponseBody and #ExceptionHandler

I have been trying to get exception handling working in my simple Spring 3 based ReST web services. Based on everything I have seen, there is a bug that prevents this from working automatically with the #ResponseBody and #ExceptionHandler annotations
https://jira.springsource.org/browse/SPR-6902
So given that it isn't supported until Spring 3.1 or 3.0.6, what is the current best method for doing exception handling? I have seen numerous posts but haven't found a clear answer that has worked for me. An ideal solution would be one that automatically provides support for both xml and json
Do I have to manually define the entire marshalling setup? Won't this remove the need for the annotations that make using Spring 3 rest support worth it?
Seems in order to manually define marshalling (i.e. Jaxb2Marshaller) I need to add a new dependency on spring-ws which is a bit of a pain
Is it easier to just define a 'Response' object that all my methods return and wrap all functions in try/catch blocks?
You can redirect on error and then return something in #ResponseBody:
#ExceptionHandler(Exception.class)
public ModelAndView handleMyException(Exception exception) {
return new ModelAndView("redirect:errorMessage?error="+exception.getMessage());
}
#RequestMapping(value="/errorMessage", method=RequestMethod.GET)
#Responsebody
public String handleMyExceptionOnRedirect(#RequestParameter("error") String error) {
return error;
}
Little ugly, but this is just work around till the fix will be available.
This is a good workaround, but with one addition. The #ExceptionHandler(Exception.class)
should be #ExceptionHandler(MyException.class, YourException.class) as you can get into a loop using the general Exception class.
You can then test for (ex instanceof Myexception) to determine the message to display if need be.

Resources