I'm trying to use #DELETE request after a made some simple web application which I've tested using soapui. With this application I can add and get users/book to database. Now I'm trying to made a #DELETE request but I can't make it. Here is the code:
//UserServiceImpl
#PersistenceContext
private EntityManager em;
#Override
public void deleteUser(Long id) {
if (null == id || id.longValue() < 1) {
throw new IllegalArgumentException(" User id can not be null or less than zero. ");
}
User u = em.find(User.class, id);
em.remove(u);
}
//UserResource
#Autowired
private UserService userService;
#DELETE
#Path("/delete/{id}")
public Response deleteUser(#PathParam("id") String id) {
Response response;
try {
User user = userService.deleteUser(Long.valueOf(id));//here is the error
if (user != null) {
response = Response.status(HttpServletResponse.SC_OK).entity(user).build();
} else {
response = Response.status(HttpServletResponse.SC_NOT_FOUND).build();
}
} catch (IllegalArgumentException e) {
response = Response.status(HttpServletResponse.SC_NOT_FOUND).build();
}
return response;
}
I`ve fix my problem. The delete method which is in UserServiceImpl must not be void.... it must be public User deleteUser(Long id). The other delete method in Resource class ... just need to be of void type. There i do not use Response and i simply print the result like this:
System.out.print(Response.status(HttpServletResponse.SC_OK).entity(user).build());
Related
I am trying to create login function and I want to save in the session specific data to use in future requests of the user is it possible?
In the loginUser, first if is always false even if the user already logged
and same in the updatePassword .
I need to save the attribute from the function loginUserToSession. Any idea why it doesn't work ?
here is my code
Resource
#Path("/logIn")
#Singleton
public class UserResource extends baseResource<UserDao, UserEntity>
{
#Path("/authenticateUser")
#GET
#UnitOfWork
public String loginUser(#Context HttpServletRequest req #QueryParam("callback") String callback, #QueryParam("loginInfo") LoginInfo loginInfo) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
return ResourceResponse.getResourceJsonString("null", callback, "true", ErrorMessageEnum.SUCCESS);
}
String userName = loginInfo.username;
String plainTextPassword = loginInfo.password;
UserEntity user = objectDao.logIn(userName, plainTextPassword);
if(user != null)
{
SessionManager.loginUserToSession(req, user.getUserId(), userName);
return ResourceResponse.getResourceJsonString(user.getUserStatus(), callback, "true", ErrorMessageEnum.SUCCESS);
}
return ResourceResponse.getResourceJsonString("null", callback, "false", ErrorMessageEnum.LOGIN_FAILED);
}
#Path("/updatePassword")
#GET
#UnitOfWork
public String updatePassword(#Context HttpServletRequest req, #QueryParam("callback") String callback, #QueryParam("oldPwd") String oldPwd, #QueryParam("newPwd") String newPwd) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
short userId = SessionManager.getUserId(req);
ObjectDaoResponse res = objectDao.updatePassword(userId, oldPwd, newPwd);
return ResourceResponse.getResourceJsonString(res.getObjectJsonString(), callback, res.getSuccess(), res.getCode());
}
else
{
return ResourceResponse.getResourceFailResponseString(callback, ErrorMessageEnum.USER_NOT_CONNECTED);
}
}
}
SessionManager.java
public static void loginUserToSession(HttpServletRequest req, short userId, String userName)
{
if(req == null)
{
return;
}
HttpSession session = req.getSession(true);
session.setAttribute(ATTRIBUTE_USER_NAME, userName);
session.setAttribute(ATTRIBUTE_USER_ID, userId);
session.setAttribute(ATTRIBUTE_USER_CONNECTED, true);
}
public static boolean isUserConnected(HttpServletRequest req)
{
if(req == null)
{
return false;
}
HttpSession session = req.getSession(false);
if(session != null)
{
boolean userConnected = (boolean) session.getAttribute(ATTRIBUTE_USER_CONNECTED);
if(userConnected)
{
return userConnected;
}
System.out.Println("session.getAttribute(ATTRIBUTE_USER_CONNECTED)== null");
}
return false;
}
Please change into Resource like this:
public String loginUser(#Context HttpServletRequest req #QueryParam("callback") String callback, #QueryParam("loginInfo") LoginInfo loginInfo) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
return ResourceResponse.getResourceJsonString("null", callback, "true", ErrorMessageEnum.SUCCESS);
}else{
String userName = loginInfo.username;
String plainTextPassword = loginInfo.password;
UserEntity user = objectDao.logIn(userName, plainTextPassword);
if(user != null)
{
SessionManager.loginUserToSession(req, user.getUserId(), userName);
return ResourceResponse.getResourceJsonString(user.getUserStatus(), callback, "true", ErrorMessageEnum.SUCCESS);
}
}
}
Above was the flow error , whatever i got, Now you have to setattribute into session scope then use this:
HttpSession session = request.getSession();
session.setAttribute("UserName", "Usename_Value");
Or for request Scope use this:
request.setAttribute("attributeName",yourStringVAlue);
It turns out that for some reason google postman don't send the HttpServletRequest as it should be. so jersey translate it like new user and create an empty new HttpServletRequest. Conclusion do not test your server side with Google's postman
when i try to send the request from my client it work fine.
Here is my Authentication filter :
public class AuthenticationFilter implements ContainerRequestFilter {
private static Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);
#Autowired
private AuthenticationService service;
#Override
public void filter(ContainerRequestContext context) throws IOException {
String token = context.getHeaderString("mytoken");
if (token == null || token.isEmpty()) {
String message = "token.null_empty";
logger.warn("{}: Token is required to access to personal data (resource {}) => reject request", message, context.getUriInfo().getBaseUri());
throw new AuthenticationException(ErU2, message);
}
// check token and retrieve user information
logger.debug("Checking validity of token {}", token);
IUser user = this.service.getUser(token);
logger.warn("======= AuthenticationFilter#filter token={}, user={}", token, user);
// set user data as request property
context.setProperty("user", user);
logger.warn("======= AuthenticationFilter#filter token={}, user#context.setProperty={}", token, (IUser) context.getProperty("user"));//In this line ihave user not null
}
}
#Path("perso")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
#Component
public class PersonalSpace {
private static Logger logger LoggerFactory.getLogger(PersonalSpace.class);
#Context
private ContainerRequestContext context;
private IUser getUser() {
logger.debug("[IN] PersonalSpace#getUser");
IUser user = (IUser) this.context.getProperty("user");//This returns null
logger.warn("======= PersonalSpace#getUser user={}", user);
return user;
}
#GET
#Path("/skanso/data")
public Response getData(#QueryParam("start") Integer start, #QueryParam("number") Integer number,
List<Integer> ids) {
return dataOperator.getDataLimitedList(getUser(), start, number, ids);
}
}
This code works nicely when i test with single request , but on concurrent request this.context.getProperty("user") returns null.
Is there à solution threadSafe or something like that ?
Please save my hair :)
I am using #With(Action.class) annotation to intercept the calls to specific controller/actions. I am trying to retrieve the session from database on in the interceptor function; however the JPA helper class is not available in the Action.class interceptor method "call".
Can someone please guide on how to retrieve database entities in the interceptor functions?
Thanks.
Interceptor class:
public class SecuredAction extends Simple {
public SecuredAction() {
// TODO Auto-generated constructor stub
}
#Override
public Promise<Result> call(Context ctx) throws Throwable {
// check isContactVerified/isEmailVerified
String sid = getSidFromCookie(ctx);
if (sid != null) {
Session appSession = (Session) JPA.em().createNamedQuery("Session.findBySessionId").getSingleResult();
User user = appSession.getUserId();
if (user != null) {
ctx.args.put("user", user);
return delegate.call(ctx);
}
}
Result unauthorized = Results.unauthorized("Invalid Session");
return F.Promise.pure(unauthorized);
}
private String getSidFromCookie(Http.Context ctx) {
return ctx.session().get(AppConstants.COOKIE_USER_SESSIONID);
}
}
Error:
[RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with #play.db.jpa.Transactional]
Wrap body of you action with JPA.withTransaction:
return JPA.withTransaction(
"default",
false, () -> {
String sid = getSidFromCookie(ctx);
if (sid != null) {
Session appSession = (Session) JPA.em().createNamedQuery("Session.findBySessionId").getSingleResult();
User user = appSession.getUserId();
if (user != null) {
ctx.args.put("user", user);
return delegate.call(ctx);
}
}
Result unauthorized = Results.unauthorized("Invalid Session");
return F.Promise.pure(unauthorized);
}
);
And do not annotate method with #Transactional if you annotated it with #With(SecuredAction.class).
My Question is How can I validate request parameters if I use #PathParam.
For instance I have two request parameters, name and id
path is localhost:/.../search/namevalue/idvalue
if a user submits blanks for name or id I should send a response mentioning that name is required/ id is required.
I could do the validations if I use #QueryParam, but I'm not sure how to do it if I have to use pathvariables.
If I just test using http:/localhost:/.../search/namevalue orhttp:/localhost:/.../search/idvalue or http:/localhost:/.../search/ it's throwing servlet exception.
Below is the code, if i use QueryParams validations work just fine, Please let me know the approach when i use pathparam
#Controller
#Path("/customer")
public class CustomerController extends BaseController implements Customer {
#Override
#GET
#Produces({ "application/json", "application/xml" })
#Path("/search/{name}/{id}/")
public Response searchCustomerDetails(
#PathParam("name") String name,
#PathParam("id") Integer id) {
ResponseBuilder response = null;
CustomerValidations validations = (CustomerValidations) getAppContext()
.getBean(CustomerValidations.class);
CustomerResponse customerResponse = new CustomerResponse();
CustomerService customerService = (CustomerService) getAppContext()
.getBean(CustomerService.class);
try {
validations.searchCustomerDetailsValidation(
name, id,customerResponse);
if (customerResponse.getErrors().size() == 0) {
CustomerDetails details = customerService
.searchCustomerDetailsService(name, id);
if (details == null) {
response = Response.status(Response.Status.NO_CONTENT);
} else {
customerResponse.setCustomerDetails(details);
response = Response.status(Response.Status.OK).entity(
customerResponse);
}
} else {
response = Response.status(Response.Status.BAD_REQUEST).entity(
customerResponse);
}
}
catch (Exception e) {
LOGGER.error(e.getMessage());
response = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
}
return response.build();
} }
#Component
#Scope("prototype")
public class CustomerValidations {
public void searchCustomerDetailsValidation(
String name, Integer id,
CustomerResponse customerResponse) {
if (id == null) {
customerResponse.getErrors().add(
new ValidationError("BAD_REQUEST",
""invalid id));
}
if (name== null
|| (name!= null && name
.trim().length() == 0)) {
customerResponse.getErrors().add(
new ValidationError("BAD_REQUEST", "invalid id"));
}
} }
#XmlRootElement
public class CustomerResponse {
private CustomerDetails customerDetails;
private List<ValidationError> errors = new ArrayList<ValidationError>();
//setters and getters }
public class ValidationError {
private String status;
private String message;
public ValidationError() {
}
public ValidationError(String status, String message) {
super();
this.status = status;
this.message = message;
}
//setters and getters }
You're receiving an exception because you have no methods mapped to #Path("/search/{foo}/") or #Path("/search/"), so you should be getting a default 404 response as these paths are not really defined.
I'm not sure why you would want to validate these "missing" request paths though - it looks like this endpoint is intended to be used as a query endpoint so I'd suggest you use #RequestParam/query parameters to more RESTfully describe the search you're attempting. A path of search/{name}/{id} would suggest a specific resource which permanently lives at this URL, though in this case you're querying for customers on this controller.
I would propose you drop the /search path completely and just map query parameters onto the "root" of the Customer controller, so you get something like
#Controller
#Path("/customer")
public class CustomerController extends BaseController implements Customer {
#GET
#Produces({"application/json", "application/xml"})
public Response searchCustomerDetails(
#RequestParam("name") String name,
#RequestParam("id") Integer id) {
// Returns response with list of links to /customer/{id} (below)
}
#GET
#Produces({"application/json", "application/xml"})
#Path("/{id}")
public Response getCustomerDetails(#PathVariable("id") String id) {
// GET for specific Customer
}
}
I have class Registration with username email password
I have following function in dao , service classes
public Registration get( Integer id ) {
logger.debug("Getting person");
return registrationDAO.findUserByID(id);
}
#Resource(name="registrationService")
private RegistrationService registrationService;
public Registration findUserByID(Integer ID) {
try {
Session session = sessionFactory.getCurrentSession();
Registration person = (Registration) session.get(Registration.class, ID);
return person;
} catch (Exception e) {
System.out.println(e);
throw new RuntimeException("DAO failed", e);
}
}
I am using that function in following function
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// Declare a null Spring User
UserDetails user = null;
logger.debug(username);
//for testing -- i get error here
Registration regUser = registrationService.get(1);
logger.debug(regUser);
try {
DbUser dbUser = userDAO.searchDatabase(username);
I get error when i add this line
Registration regUser = registrationService.get(1);
logger.debug(regUser);
Edit: For clarified question
#Resource
private RegistrationService registrationService;
See the tutorial at: http://download.oracle.com/javaee/5/tutorial/doc/bncjk.html#bncjl