Swagger2 #ApiParam specifying type - java

I'm trying to change the type of a parameter on the generated swagger contract, but it looks like the #ApiParam#type property is not working.
ResponseEntity<Void> delete(
#ApiParam(
value = "The id of the object",
required = true,
type = "java.lang.String") Integer id);
Doing this has no effect in swagger-ui, and id is still being shown as Integer.
Does anyone knows a workaround for this?

You have to use #ApiImplicitParam
#ApiImplicitParam(dataType = "string", name = "id")
ResponseEntity<Void> delete(Integer id);

I think you should use "string" not "java.lang.String".
The annotation is not #ApiParam, you can use #ApiImplicitParam, and use dataType="string"
The supported type as below:
integer
long
float
double
string
byte
boolean
date
dateTime

Related

nullValuePropertyMappingStrategy not working

I have the following mapper
#Mapper(config = MappingConfig.class)
public interface PokerRoomMapper {
#Mapping(target = "phase", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);
}
The pokerRoomDto which is passed to it has a "phase" field which can be null. I want this field to be ignored when it is null. But right now the "null" value still gets mapped to the pokerRoom entity.
If I just ignore the field in the mapper it works and the default value for phase in PokerRoom stays untouched however I dont want to always ignore it.
#Mapper(config = MappingConfig.class)
public interface PokerRoomMapper {
#Mapping(target = "phase", ignore = true)
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);
}
This works as designed. NullValuePropertyMappingStrategy is only applied to update method. It is not used for normal mappings.
I think that you are looking for NullValueCheckStrategy, if you use NullValueCheckStrategy#ALWAYS then MapStruct will always do a null check non the PokerRoomDto and only invoke the setter on the PokerRoom if the value was not null
If you initialise your field at declaration and want to keep that value, I've come up with a solution.
A bit hacky, not very general (depends on generated variable name), but works.
Assuming:
class PokerRoom {
Integer phase = 0;
}
You can use
#Mapping(target = "phase", defaultExpression = "java( pokerRoom.getPhase() )")
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);
A simpler solution would be to use the same constant you use at field declaration.
#Mapping(target = "phase", defaultValue = "0")
PokerRoom pokerRoomDtoToPokerRoom(PokerRoomDto pokerRoomDto);

Spring Boot Failed to Convert JSON to pojo from POST request for fields that are not of type string

public class Dog {
private String name;
private int weight;
//...getters and
//setters and constructor
}
Controller:
#RequestMapping(value = "/dogs", method = RequestMethod.POST,
produces = "application/json")
public void createDog(Dog dog) {
dr.save(dog);
}
How come when I call the endpoint with json {"name":"bark", "weight":50}
I get an error:
Failed to convert value of type 'null' to required type 'int'; nested
exception is
org.springframework.core.convert.ConversionFailedException: Failed to
convert from type [null] to type [int] for value 'null'; nested
exception is java.lang.IllegalArgumentException: A null value cannot
be assigned to a primitive type",
"objectName": "dog",
"field": "weight",
"rejectedValue": null,
"bindingFailure": true,
"code": "typeMismatch"
"message": "Validation failed for object='dog'. Error count: 1
edit: I get the same issue with booleans and doubles. I guess I have to use objects not primitives?
Add the annotation #RequestBody to the param dog in your create method
Need to specify the #RequestBody annotation to specify we are sending DOG object as part of request body:
#RequestMapping(value = "/dogs", method = RequestMethod.POST, produces = "application/json")
public void createDog((**#RequestBody** Dog dog) { dr.save(dog); }
Only works with objects so use Integer instead of int.
If exist possibility object receive null, you can't use type primitives, same int, char, boolean.
private int weight
Use type objects same Integer, Boolean ... for one type primitive has a Object, then can receive null value.

Add optional query parameter using spring data mongodb repository

I want to add optional query parameters using spring data mongodb.
Controller code:
#RestController
private final ActionService actionService;
#RequestMapping(value = "/action/{id}", method = RequestMethod.GET)
public ResponseEntity<List<Action>> getActionList(#PathVariable("id") long id,
#RequestParam(value = "actionType", required = false) ActionType actionType,
#RequestParam(value = " ", required = false) String[] params) {
List<Action> actionList = actionService.getAction(id, actionType, params);
return new ResponseEntity<>(actionList, HttpStatus.OK);
}
ActionServiceImpl.java
private ActionRepository actionRepository;
public List<Action> getAction(long id, ActionType type, String... var1) {
return actionRepository.getByActionType(id, type, var1.length > 0 ? var1[0] : "", var1.length > 1 ? var1[1] : "", var1.length > 2 ? var1[2] : "");
}
ActionRepository.java
#Repository
public interface ActionRepository extends MongoRepository<Action, String> {
#Query(value = "{ 'id' : ?0 , 'actionType' : ?1 , 'param1' : ?2 , 'param2': ?3 , 'param3' : ?4 } ")
List<Action> getByActionType(long id, ActionType type, String var1, String var2, String var3);
}
Note: 'id' is mandatory field and action type and params are optional. I want to get data based on 'id' whether I pass action type/params or not. Currently, i am getting null pointer exception in 'ActionServiceImpl' as I am not passing params and action Type. 'Action Type' is enumeration.
Can someone help me to change ActionRepository #Query tag so, that I can get data based on id without passing actionType or params. e.g. if I pass action type then mongo query should give result based on 'id $or actionType'.
You cannot achieve this using #Query. Other possible alternatives are
Create two methods in Repository class. One which takes only id and other which takes id and other arguments. And in your service class, you can decide which one to call based on the data in hand. (Not Scalable)
Use QueryDsl. With this you can create search criteria based on data you have dynamically. Some helpful links
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#core.extensions.querydsl
http://www.baeldung.com/queries-in-spring-data-mongodb
You can use Example. Here is the link for documentation.(This has some limitations)
In my personal experience using QueryDsl is the best way to tackle these cases and it can be easily extended for further changes in requirement.

How to give default value as integer in #RequestParam()

I'm new to spring boot and learning #RequestParam()
I know that we can give defaultValue in String but when I am trying to give default value as Integer it's showing me an error.
#RequestMapping("/returnVeriable")
public int getVeriable(#RequestParam(required=true,defaultValue=1/*error here*/) int veri){
return veri;
}
any help would be appreciated.
Try with "" around integer to make it string as the defaultValue is implemented as String.
#RequestMapping("/returnVeriable")
public int getVeriable(#RequestParam(required=true,defaultValue="1") Integer veri){
return veri;
}
refer : https://jira.spring.io/browse/SPR-5915
When a value traffic by HTTP protocol, it has no type. It's a String. And so it is at this parameter type at the annotation. Then, you do something like this:
#RequestParam(required = true, defaultValue = "1") Integer veri
And it will work fine.
This should work
#RequestMapping("/returnVariable")
public int getVariable(#RequestParam(required=true,defaultValue="1") int var) {
return var;
}
By default what ever you pass to the controller is treated as String and converted to respective types. So even default values need to be set as String

JPA: Parameterized instances of AttributeConverter

We are developing an application connected to a legacy database. This is very "untyped", using strings for almost all data. What is worse is that is far of being homogeneous: it uses different patterns for dates or times ('YYDDMM', 'HHMMSS', milliseconds) and booleans ('Y'/'N', 'X'/' '), for example.
We want to use JPA (EclipseLink) and custom converters. The problem is that #Convert expects a class implementing AttributeConverter, so we have to do new classes for each pattern. What I'd like is a BooleanConverter class, which can be instantiated with values 'Y'/'N' or 'X'/' '.
This is obviously out of JPA spec, but maybe it's possible using EclipseLink annotations/configuration. Looking at its #Convert annotation, a converter can be specified by name. This sounds good to me if I can register a ynBooleanConverter and xSpaceBooleanConverter:
// Unfortunately, this method does not exist :(
Session.addConverter('ynBooleanConverter', new BooleanConverter("Y", "N"));
#Entity
public class MyEntity {
#Convert("ynBooleanConverter")
private Boolean myBoolean;
...
}
Is it possible? What other options do we have?
Try #ObjectTypeConverter:
#Entity
#ObjectTypeConverters({
#ObjectTypeConverter(name = "ynBooleanConverter", objectType = Boolean.class, dataType = String.class,
conversionValues = {
#ConversionValue(objectValue = "true", dataValue = "Y"),
#ConversionValue(objectValue = "false", dataValue = "N") }),
#ObjectTypeConverter(name = "xSpaceBooleanConverter", objectType = Boolean.class, dataType = String.class,
conversionValues = {
#ConversionValue(objectValue = "true", dataValue = "X"),
#ConversionValue(objectValue = "false", dataValue = " ") }),
})
public class MyEntity {
#Convert("ynBooleanConverter")
private boolean ynBoolean;
#Convert("xSpaceBooleanConverter")
private boolean xSpaceBoolean;
}
So your Converter behaves different depending on some state in the context? I think I would try to bind the context info to a threadlocal variable which I can read back in the Converter implementation.
Do you have access to a CDI-implementation? Then its even more elegant to inject some bean with your context info into your Converter-implementation. You mentioned that you are missing some session-Methods? Maybe a #SessionScope'ed bean will help you.
Sadly #Inject is not specified in a converter class. You will need to lookup the bean "by hand" like mentioned in this post.
Too late to this thread, but here is a blog post which shows how JPA converters are to be written. Has working code for String and LocalDate conversions.

Categories

Resources