I am creating a method for an API. In this method i have some parameters that are optional. those are filters for searching an event. when i try to run it and type the following url:
http://localhost:8181/api/events?id=gRDHzDh9TdiLDAZgrZc2wg==
i get this error message:
Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: Invalid UUID string: gRDHzDh9TdiLDAZgrZc2wg==
So i understand that i insert a String in my url and expect a UUID in code, but how do i convert this? Below here is my code:
#RequestMapping(
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity getEvents(#RequestParam(value = "id", required = false) UUID eventId,
#RequestParam(value = "title", required = false) String title,
#RequestParam(value = "playtype", required = false) PlayType playType,
#RequestParam(value = "skilllevel", required = false) SkillLevel skillLevel,
#RequestParam(value = "sporttype", required = false) SportType sportType,
#RequestParam(value = "long", required = false) String _long,
#RequestParam(value = "lat", required = false) String lat) {
try {
List<Event> events = eventService.getEvents(eventId, title, playType, skillLevel, sportType, _long, lat);
if (events.size() == 0) {
return new ResponseEntity("No events found", HttpStatus.OK);
}
return new ResponseEntity(events, HttpStatus.OK);
} catch (Exception ex){
return new ResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
So here are my 2 questions:
How do i convert the string to a valid UUID input in the RequestParam?
How do i convert the string to a valid enum in the RequestParam? (because with the enums i have the same error)
EDIT
my code is now like this:
#RequestMapping(
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity getEvents(#RequestParam(value = "id", required = false) String eventId,
#RequestParam(value = "title", required = false) String title,
#RequestParam(value = "playtype", required = false) String playType,
#RequestParam(value = "skilllevel", required = false) String skillLevel,
#RequestParam(value = "sporttype", required = false) String sportType,
#RequestParam(value = "long", required = false) String _long,
#RequestParam(value = "lat", required = false) String lat) {
UUID id = null;
PlayType playType1 = null;
SkillLevel skillLevel1 = null;
SportType sportType1 = null;
try {
if (eventId != null){
id = UUID.fromString(eventId);
}
if (playType != null){
playType1 = PlayType.valueOf(playType);
}
if (skillLevel != null){
skillLevel1 = SkillLevel.valueOf(skillLevel);
}
if (sportType != null){
sportType1 = SportType.valueOf(sportType);
}
List<Event> events = eventService.getEvents(id, title, playType1, skillLevel1, sportType1, _long, lat);
if (events.size() == 0) {
return new ResponseEntity("No events found", HttpStatus.OK);
}
return new ResponseEntity(events, HttpStatus.OK);
} catch (Exception ex){
return new ResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
but i still get an error:
Invalid UUID string: gRDHzDh9TdiLDAZgrZc2wg==
How do I convert the string to a valid UUID input?
You need to use UUID.fromString() API, see here
How do i convert the string to a valid enum?
You need to use Enum.valueOf() API, see here
Related
i am working on a spring boot project and i want ti set limitation for some service to call.for example i want in 1 minute,5 request send to this endpoint.
#GetMapping(path = "/allJobsByChartCode/{chartCode}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Page<?>> getAllOCMJobsByChartCode(#PathVariable("chartCode") String chartCode, #RequestParam int page, #RequestParam int size, #RequestParam(required = false, name = "orderby") String orderby, #RequestParam(required = false, name = "direction") String direction) {
Page<OCMJobsDTO> gridData = ocmJobsService.getAllOCmJobsByChartCode(chartCode, PageRequest.of(page, size), orderby, direction);
if (gridData.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<>(gridData, HttpStatus.OK);
}
I'm writing j-unit Test-cases for my services and in which i couldn't mock service Response properly, Which is giving me a null. can somebody help me in this issue.
public ResponseEntity<Void> lockGet(
#ApiParam(value = "Unique identifier for this request.", required = true) #RequestHeader(value = "service-id", required = true) String serviceId,
#ApiParam(value = "Logged in userid.", required = true) #RequestHeader(value = "user-id", required = true) String userId,
#ApiParam(value = "Unique messageid.", required = true) #RequestHeader(value = "message-id", required = true) String messageId,
#RequestHeader(value = "access-token", required = true) String accessToken,
#ApiParam(value = "Unique id of the doamin of the entity", required = true) #RequestParam(value = "lockDomainId", required = true) Long lockDomainId,
#ApiParam(value = "Unique id of the entity to be fetched", required = true) #RequestParam(value = "lockEntityId", required = true) Long lockEntityId,
HttpServletRequest request, HttpServletResponse response) {
ResponseEntity<Void> result = null;
if (request.getAttribute("user-id") != null)
userId = (String) request.getAttribute("user-id");
String logContext = "||" + lockDomainId + "|" + lockEntityId + "||";
ThreadContext.put("context", logContext);
long t1 = System.currentTimeMillis();
LOG.info("Method Entry: lockGet" + logContext);
ServiceRequest serviceRequest = AppUtils.mapGetRequestHeaderToServiceRequest(serviceId, userId, lockDomainId,
lockEntityId);
try {
ServiceResponse serviceResponse = lockService.getLock(serviceRequest);
// set all the response headers got from serviceResponse
HeaderUtils.setResponseHeaders(serviceResponse.getResponseHeaders(), response);
result = new ResponseEntity<Void>(HeaderUtils.getHttpStatus(serviceResponse));
} catch (Exception ex) {
LOG.error("Error in lockGet", ex);
result = new ResponseEntity<Void>(HttpStatus.INTERNAL_SERVER_ERROR);
}
ThreadContext.put("responseTime", String.valueOf(System.currentTimeMillis() - t1));
LOG.info("Method Exit: lockGet");
return result;
}
#Test
public void testLockGetForError() {
request.setAttribute("user-id","TestUser");
ServiceRequest serviceRequest = new ServiceRequest();
serviceRequest.setUserId("TestUser");
ServiceResponse serviceResponse = new ServiceResponse();
LockService service = Mockito.mock(LockService.class);
when(service.getLock(serviceRequest)).thenReturn(serviceResponse);
// ServiceResponse serviceResponse = lockService.getLock(serviceRequest);
ResponseEntity<Void> result = new ResponseEntity<Void>(HeaderUtils.getHttpStatus(serviceResponse));
ResponseEntity<Void> lockGet = lockApiController.lockGet("1234", "TestUser", "TestMessage", "TestTkn", 12345L, 12345L, request, response);
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, lockGet.getStatusCode());
}
I tried in different scenario's which couldn't fix this issue. Can someone help me out. Thanks in advance.
From the code that you have put , the issue that i see is that you are actually mocking the LockService object but when calling the lockApiController.lockGet method the code is not actually working with the mocked LockService since lockApiController has an LockService object of it's own.
One way to solve this issue is to inject the mocked LockService
object into the lockApiController object using #Spy. This way
when the getLock() is called it will be actually called on the
mocked object and will return the mock response provided.
So in your test :
#Test
public void testLockGetForError() {
LockService service = Mockito.mock(LockService.class);
LockApiController lockApiController = Mockito.spy(new LockApiController(service));
request.setAttribute("user-id","TestUser");
ServiceRequest serviceRequest = new ServiceRequest();
serviceRequest.setUserId("TestUser");
ServiceResponse serviceResponse = new ServiceResponse();
when(service.getLock(serviceRequest)).thenReturn(serviceResponse);
// ServiceResponse serviceResponse = lockService.getLock(serviceRequest);
ResponseEntity<Void> result = new ResponseEntity<Void>(HeaderUtils.getHttpStatus(serviceResponse));
ResponseEntity<Void> lockGet = lockApiController.lockGet("1234", "TestUser", "TestMessage", "TestTkn", 12345L, 12345L, request, response);
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, lockGet.getStatusCode());
}
So you can try passing the mocked LockService object to the spy object.
Another way is to try using the #InjectMocks to inject the mocked
object into the LockApiController.
#InjectMocks marks a field on which injection should be performed. Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection – in this order. If any of the given injection strategy fail, then Mockito won’t report failure.
For example:
#Mock
Map<String, String> wordMap;
#InjectMocks
MyDictionary dic = new MyDictionary();
#Test
public void whenUseInjectMocksAnnotation_thenCorrect() {
Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");
assertEquals("aMeaning", dic.getMeaning("aWord"));
}
For the class:
public class MyDictionary {
Map<String, String> wordMap;
public MyDictionary() {
wordMap = new HashMap<String, String>();
}
public void add(final String word, final String meaning) {
wordMap.put(word, meaning);
}
public String getMeaning(final String word) {
return wordMap.get(word);
}
}
For both of these to work , you must be having a constructor or appropriate setters to set the mock object to the LockApiController class.
Reference : https://howtodoinjava.com/mockito/mockito-annotations/
i was trying to update database tables by using following Hibernate Query Language
#RequestMapping(value = "/update",method = RequestMethod.POST)
public #ResponseBody String update(#RequestParam(value = "score1",required = true) String score1,
#RequestParam(value = "score2",required = true) String score2,
#RequestParam(value = "score3",required = true) String score3,
#RequestParam(value = "score4",required = true) String score4,
#RequestParam(value = "id",required = true)String id,
Model model)
{
SessionFactory sessionFactory=new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(User.class)
.addAnnotatedClass(UserDetail.class)
.addAnnotatedClass(UserScores.class).buildSessionFactory();
Session session=sessionFactory.getCurrentSession();
try
{
System.out.println("ID is"+id);
session.beginTransaction();
session.createQuery("update UserScores u set " +
"u.score1=:score1," +
"u.score2=:score2," +
"u.score3=:score3," +
"u.score4=:score4 where u.ID=:id")
.setParameter("score1",score1)
.setParameter("score2",score2)
.setParameter("score3",score3)
.setParameter("score4",score4)
.setParameter("id",id);
session.getTransaction().commit();
session.close();
}
catch (Exception e)
{
System.out.println(e);
}
return score1+score2+score3+score4;
}
after executing this code, it doesnt give any error , but the data is not updated in the database
what is the problem in executing this code
Its working, i tried it in another way
#RequestMapping(value = "/update",method = RequestMethod.POST)
public #ResponseBody String update(#RequestParam(value = "score1",required = true) String score1,
#RequestParam(value = "score2",required = true) String score2,
#RequestParam(value = "score3",required = true) String score3,
#RequestParam(value = "score4",required = true) String score4,
#RequestParam(value = "id",required = true)String id,
Model model)
{
SessionFactory sessionFactory=new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(User.class)
.addAnnotatedClass(UserDetail.class)
.addAnnotatedClass(UserScores.class).buildSessionFactory();
Session session=sessionFactory.getCurrentSession();
try
{
session.beginTransaction();
System.out.println("ID is"+id);
UserScores userScores=session.get(UserScores.class,Integer.parseInt(id));
userScores.setScore1((Double.parseDouble(score1)));
userScores.setScore2((Double.parseDouble(score2)));
userScores.setScore3((Double.parseDouble(score3)));
userScores.setScore4((Double.parseDouble(score4)));
session.update(userScores);
session.getTransaction().commit();
session.close();
}
catch (Exception e)
{
System.out.println(e);
}
The query that you are creating needs to be executed using query.executeUpdate()
session.beginTransaction();
Query query = session.createQuery("update UserScores u set " +
"u.score1=:score1," +
"u.score2=:score2," +
"u.score3=:score3," +
"u.score4=:score4 where u.ID=:id");
query.setParameter("score1",score1)
query.setParameter("score2",score2)
query.setParameter("score3",score3)
query.setParameter("score4",score4)
query.setParameter("id",id);
query.executeUpdate();
session.getTransaction().commit();
session.close();
An alternative way is to make changes to the persistent entities. In this case the updates will be automatically propogated.
#ApiOperation(value = "获取打卡信息", notes = "获取打卡信息")
#RequestMapping(method = RequestMethod.GET, value = "/{mPhone}/{mPassword}/{date}")
#ApiImplicitParams({
#ApiImplicitParam(name = "mPhone", value = "手机号", required = true, dataType = "String",defaultValue="13268690268",paramType="Path"),
#ApiImplicitParam(name = "mPassword", value = "密码", required = true, dataType = "String",defaultValue="111111",paramType="Path"),
#ApiImplicitParam(name = "date", value = "日期", required = true, dataType = "String",defaultValue="2017-07-04",paramType="Path"),
#ApiImplicitParam(name = "httpSession", value = "Session", required = false)})
public #ResponseBody String getSignInfo(#PathVariable String mPhone, #PathVariable String mPassword,
#PathVariable String date,
HttpSession httpSession) {
.......
}
enter image description here
I want to remove this parameter (httpSession) from the document, and I need help。
Springfox won't show these values by default. The reason why httpSession is visible in your case, is because you added it by yourself as an implicit parameter:
#ApiImplicitParam(name = "httpSession", value = "Session", required = false)
If you don't want the httpSession to pop up, remove that from your implicit parameters. Additionally, you don't even have to use #ApiImplicitParam in your case, you can use #ApiParam:
#ApiOperation(value = "获取打卡信息", notes = "获取打卡信息")
#RequestMapping(method = RequestMethod.GET, value = "/{mPhone}/{mPassword}/{date}")
public #ResponseBody String getSignInfo(
#ApiParam(value = "手机号", required = true, dataType = "String",defaultValue="13268690268")
#PathVariable String mPhone,
#ApiParam(value = "密码", required = true, dataType = "String",defaultValue="111111")
#PathVariable String mPassword,
#ApiParam(value = "日期", required = true, dataType = "String",defaultValue="2017-07-04")
#PathVariable String date,
HttpSession httpSession) {
// ...
}
Actually, i have this Rest Template request:
#RequestMapping(value = "/uploadProperties", method = RequestMethod.POST)
public #ResponseBody RessourceMetadata uploadProperties(
#RequestParam(value = "group", required = true) String group,
#RequestParam(value = "id", required = true) String id,
#RequestParam(value = "version", required = true) String version,
#RequestParam(value = "env", required = true) String env) {
try {
Ressource ressource = new Ressource(content, group, id, version, env, PropertiesFileUtils.getPropertiesFilename());
getRessourceService().save(ressource);
return ressource.getMetadata();
} catch (RuntimeException e) {
log.error("Error while uploading.", e);
throw e;
} catch (Exception e) {
log.error("Error while uploading.", e);
throw new RuntimeException(e);
}
}
I want to add a #RequestBody like this:
#RequestBody #RequestParam(value = "content", required = true) ????? content
this new content can contain anything.
How do I pass the content parameter correctly?
Declare a class like this
class PostBody{
Map<String, String> content;
}
use this PostBody as #RequestBody. You can pass any string key value pair to this structure. Something like this
{
"content":
{
"version" : "1.1",
"env" : "test"
}
}
or
{
"content":
{
"version" : "1.1",
"env" : "test",
"id" : "1.1"
}
}