How to read a cookie in JAX-RS (Jersey) - java

I followed this guide to read and create cookies but I can only read cookie that I create from the same subdomain.
For example if I create a cookie in http://localhost:8080/x/y/test/create I can read it from: http://localhost:8080/x/y/test/read but I cannot read it from http://localhost:8080/x/y/test2/read (Note the difference between test and test2)
Where is the problem? How could I read the cookie everywhere in my domain?
Here is the code:
CLASS 1
#Path("test")
public class Test {
#GET
#Path("/create")
#Produces(MediaType.TEXT_PLAIN)
public Response login() {
NewCookie cookie = new NewCookie("name", "123");
return Response.ok("OK").cookie(cookie).build();
}
#GET
#Path("/read")
#Produces(MediaType.TEXT_PLAIN)
public Response foo(#CookieParam("name") String value) {
System.out.println(value);
if (value == null) {
return Response.serverError().entity("ERROR").build();
} else {
return Response.ok(value).build();
}
}
}
CLASS 2
#Path("test2")
public class Test2 {
#GET
#Path("/read")
#Produces(MediaType.TEXT_PLAIN)
public Response foo(#CookieParam("name") String value) {
System.out.println(value);
if (value == null) {
return Response.serverError().entity("ERROR").build();
} else {
return Response.ok(value).build();
}
}
}
EDIT
The problem was at creation time. Now I create the cookie in this way:
NewCookie cookie = new NewCookie("name", "123", "/", "", "comment", 100, false);

It's a default behavior.
To set cookie to your domain, use another constructor for cookie, and set empty domain and root path:
domain = ""
path = "/"

Related

Redirect from Spring REST controller with parameters

I have two different Spring applications (app-one, app-two), app-one should receive a response and then redirect to app-two with some parameters. So, I have the following REST controller in app-one:
#RestController
public class RedirectController
{
#GetMapping(value = "/redirect")
public ResponseEntity<Void> redirectEndpoint(HttpServletRequest request,
RedirectAttributes redirectAttributes)
{
// Do some business logic
// Set parameters
redirectAttributes.addAttribute("attribute", "Value 1");
redirectAttributes.addFlashAttribute("flashAttribute", "Value 2");
// Redirect to success URL
String redirectURL = "http://app-two/success";
HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create(redirectURL));
return ResponseEntity.status(HttpStatus.FOUND).headers(headers).build();
}
}
And the following REST controller in app-two:
#RestController
public class SuccessController
{
#GetMapping(value = "/success")
public ResponseEntity<Void> successEndpoint(HttpServletRequest request, Model model,
#RequestParam(value = "attribute", required = false) String attribute,
#ModelAttribute(value = "flashAttribute") String flashAttribute)
{
// Get parameters
System.out.println("attribute: " + attribute);
System.out.println("flashAttribute: " + flashAttribute);
String flashAttributeFromModelMap = (String) model.asMap().get("flashAttribute");
System.out.println("flashAttributeFromModelMap: " + flashAttributeFromModelMap);
Map<String, ?> flashMap = RequestContextUtils.getInputFlashMap(request);
if (flashMap != null)
{
String flashAttributeFromFlashMap = (String) flashMap.get("flashAttribute");
System.out.println("flashAttributeFromFlashMap: " + flashAttributeFromFlashMap);
}
// Do some business logic
return ResponseEntity.status(HttpStatus.OK).build();
}
}
I was able to redirect successfully by returning FOUND (302). But when adding attributes to RedirectAttributes (in this case attribute and flashAttribute), these attributes are not found after the redirection done (attribute gets null and flashAttribute gets empty).
I tried to get the attributes values by different ways (#RequestParam, #ModelAttribute, model.asMap().get(), and RequestContextUtils.getInputFlashMap(request).get()) but none of them gets the correct value.
What I need is to get the correct attributes' values in successEndpoint. Any suggestions on how to accomplish that?
Thanks in advance.

404 error on post, but my server gets the data fine but does not return properly

I am trying to rewrite my login piece with Spring boot. Currently, my data is being posted fine and the backend is getting it, but my success function is not being fired. My backend is throwing no errors, but I am getting a 404 error on the browser.
Here is my post:
$.ajax({
type: "POST",
url: "login",
data: "&username=" + username.value + "&password=" + password.value
}).done(function(response) {
var resp = JSON.parse(response);
if (resp.loginResult === "false") {
//TODO
} else {
//TODO
}
});
Controller:
#Controller
#Scope("session")
public class LoginController {
#GetMapping("/login")
public String login() {
return "login";
}
#PostMapping("/login")
public String login(HttpServletRequest request) {
HttpSession session = request.getSession();
StringBuilder json = new StringBuilder();
String username = request.getParameter("username");
String password = request.getParameter("password");
if (userExists()) {
session.setAttribute("isLoggedIn", "true");
session.setAttribute("userID", username);
session.setAttribute("userType", "employee");
json.append("{");
json.append("\"loginResult\": \"true\",");
json.append("\"resultMessage\": \"Logged in\"");
json.append("}");
} else {
System.out.println("Username or password does not match.");
json.append("{");
json.append("\"loginResult\": \"false\",");
json.append("\"resultMessage\": \"Bad Login\"");
json.append("}");
}
return json.toString();
}
}
I am trying to just return a JSON string which can be parsed on the front end and do whatever needs to be done based off the resultMessage. Sorry if my code is ugly, I am still new to Spring and welcome any suggestions!
Here is the error in my console on the browser:
POST http://localhost:8080/BedrockWeb/login 404 ()
I am assuming I am not returning my JSON string properly.
If you use Spring, then use the conveniences that it provides. You can create following class:
public class LoginResult {
private boolean loginResult;
private String resultMessage;
public LoginResult() { }
public String getResultMessage() {
return resultMessage;
}
public boolean isLoginResult() {
return loginResult;
}
public void setLoginResult(boolean loginResult) {
this.loginResult = loginResult;
}
public void setResultMessage(String resultMessage) {
this.resultMessage = resultMessage;
}
}
Then you have to change your controller method to:
#PostMapping("/login")
#ResponseBody
public LoginResult login(HttpServletRequest request) {
HttpSession session = request.getSession();
String username = request.getParameter("username");
String password = request.getParameter("password");
LoginResult loginResult = new LoginResult();
if (userExists()) {
session.setAttribute("isLoggedIn", "true");
session.setAttribute("userID", username);
session.setAttribute("userType", "employee");
loginResult.setLoginResult(true);
loginResult.setResultMessage("Logged in");
} else {
System.out.println("Username or password does not match.");
loginResult.setLoginResult(false);
loginResult.setResultMessage("Bad Login");
}
return loginResult;
}
The #ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object. source
Yes, this is because you are not sending JSON response properly.
What you can do is create an object and set the values in that and then try to convert in JSON using
new JSONSerializer().transform(new DateTransformer("MM/dd/yyyy HH:mm:ss"), java.util.Date.class).exclude("*.class").serialize(object);
and send the response to AJAX like below:
return new ResponseEntity<String>(new JSONSerializer().transform(new DateTransformer("MM/dd/yyyy HH:mm:ss"), java.util.Date.class).exclude("*.class").serialize(object), HttpStatus.OK);
NOTE: If you want to do the same with Spring boot then the #ResponseBody annotation is enough. It will convert the object to JSON.

Return JSON object from a spring-boot rest Controller

I'm trying to check if the username is unique in spring-boot.
I want to send the result as JSON object.
This is the REST controller
#RequestMapping(value="/checkEmailUnique",method=RequestMethod.POST)
public String checkEmailUnique(#RequestBody String username){
AppUser app = userRepo.findByUsername(username);
if(app!=null){
// I want to return somthing like emailNotTaken: true
}
else{
// and here : emailNotTaken: false
}
}
I want to get the result in angular so I can show an error message in my component.
How can I do that?
Angular side
client.Service.Ts
checkEmailNotTaken(email:string){
if(this.authService.getToken()==null) {
this.authService.loadToken();
}
return this.http.post(this.host+
"/checkEmailUnique/",{email},{headers:new HttpHeaders({'Authorization':this.authService.getToken()})});
}
in client.component.ts
ngOnInit() {
this.form = this.formBuilder.group({
prenom: ['', Validators.required],
nom: ['', Validators.required],
tel: ['', Validators.required],
cin: ['', Validators.required],
username: ['', Validators.required , Validators.email , this.validateEmailNotTaken.bind(this)],
passwordG: this.formBuilder.group({
password: ['',[Validators.required,Validators.minLength(9)]],
Confirmationpassword : ['',[Validators.required,Validators.minLength(9)]]
}, {validator: passwordMatch})
});
}
validateEmailNotTaken(control: AbstractControl) {
return this.clientService.checkEmailNotTaken(control.value).map(res => {
return // what to do here ?
});
}
EDIT
#RequestMapping(value="/checkEmailUnique",method=RequestMethod.POST)
public EmailStatusCheckJson checkEmailUnique(#RequestBody final String username){
final EmailStatusCheckJson returnValue = new EmailStatusCheckJson();
AppUser app = userRepo.findByUsername(username);
if(app!=null){
returnValue.setEmailIsAvailable(false);
}
else{
returnValue.setEmailIsAvailable(true);
}
return returnValue;
}
If you are using the spring-boot-starter-web,
your project is already set to return JSON.
Instead of String as the return value from checkEmailUnique,
use an object type that you create.
Here is an example:
public class EmailStatusCheckJson
{
private Boolean emailIsAvailable;
public Boolean getEmailIsAvailable()
{
return emailIsAvailable;
}
public void setEmailIsAvailable(
final Boolean newValue)
{
emailIsAvailable = newValue
}
}
#RequestMapping(value="/checkEmailUnique",method=RequestMethod.POST)
public EmailStatusCheckJson checkEmailUnique(#RequestBody final String username)
{
final EmailStatusCheckJson returnValue = new EmailStatusCheckJson();
if (...) // email is available.
{
returnValue.setEmailIsAvailable(true);
}
else
{
returnValue.setEmailIsAvailable(false);
}
return returnValue;
}
Edited added more example.
Rest method have a return type as String .In place of any String you can use a user defined object where(inside there) put a boolean variable e.g. status there you can send whether the username is present or not. According to the response from the rest side you can forward towards angular.
You could also do this way using ResponseEntity as the return value to your RestController
public ResponseEntity<?> checkEmailUnique(#RequestBody String username){
AppUser app = userRepo.findByUsername(username);
if(null != app) {
return ResponseEntity.badRequest().build(); // Will return a 400 response
}
return ResponseEntity.ok().build(); // Will return a 200 response
}
Base on the response type you could directly identify if the email exits or not instead of returning json in this case.

How to write a request/response object from angular.js to jax-rs

I am building my backend and I need to be able to exchange a request/response object from angular.js to my backend (JAX-RS, Jersey).
My backend currently looks like this:
#POST
#Path("/search")
#ApiResponses(value = {#ApiResponse(code=200,message="returns results"),
#ApiResponse(code=404,message="not found")})
#Produces({ "application/json" })
public Response getPostShop(
#QueryParam("keyphrase") String keyphrase,
#QueryParam("product") String product,
#QueryParam("priceRange") List<Double> priceRange,
#Context SecurityContext securityContext)
throws NotFoundException {
SearchRequest searchRequest = new SearchRequest();
searchRequest.setKeyphrase(keyphrase);
searchRequest.setProduct(product);
searchRequest.setPriceRange(priceRange);
//do something with the "searchRequest"
return Response.ok(searchResponse).build();
}
Angular.Js (Something like this)
response.compose = function(searchRequest) {
return $http({
method: 'POST', //or GET
url: '/search',
data: {
searchRequest : searchRequest
},
headers: {'Content-Type':'application/json'}
});
}
where searchRequest:
$scope.searchRequest = {
'keyphrase' : $scope.keyphrase,
'product' : $scope.product,
'priceRange' : $scope.priceRange,
};
NEW GET request:
#GET
#Path("/testkeyphrase")
#ApiResponses(value = {#ApiResponse(code=200,message="returns results"),
#ApiResponse(code=404,message="not found")})
#Produces({ "application/json" })
#Consumes({ "application/json" })
public Response getTestKeyphrase(
#ApiParam(value="keyphrase that the user searches for..", required=true) TestSearchRequest testSearchRequest,
#Context SecurityContext securityContext)
throws NotFoundException {
String kyphrase = testSearchRequest.getKeyphrase();
return Response.ok(testSearchRequest).build();
}
and the TestSearchRequest is:
public class TestSearchRequest {
public TestSearchRequest(String keyphrase) {
this.setKeyphrase(keyphrase);
}
private String keyphrase;
public String getKeyphrase() {
return keyphrase;
}
public void setKeyphrase(String keyphrase) {
this.keyphrase = keyphrase;
}
}
What I need is instead of receiving all the individual parameters, to receive directly the searchRequest object and send back the SearchResponse object respectively (in JSON). Also I need the parameters to be in the body of the request and not in the URI.
Any ideas?

Spring MVC and AngularJS #RequestMapping

I have built an application with Spring-boot and AngularJS with the REST End Point application. I got a little stuck with #RequesMapping in Spring Controller I've made. The problem is, I have the example url:
"localhost:8080/foo/bar/api/cardGenerated/0102".
'01' is first parameter and '02' is second parameter. How can I mapped into #RequestMapping Spring controller to get a url above.
Here's my controller :
#RestController
#RequestMapping("/api")
public class CardGeneratedResource {
#RequestMapping(value = "/cardGenerated/{branchCode}{cardType}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<CardGenerated> get(#PathVariable("branchCode") String branchCode,
#PathVariable("cardType") String cardType,
HttpServletResponse response) {
log.debug("REST request to get CardGenerated : " + branchCode + " and " + cardType);
CardGenerated cardGenerated = cardGeneratedRepository.
findTopByBranchCodeAndCardTypeOrderByCardNumberDesc(branchCode, cardType);
if (cardGenerated == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(cardGenerated, HttpStatus.OK);
}
}
so this is my AngularJS $resource:
'use strict';
angular.module('itmApp')
.factory('CardGenerated', function ($resource) {
return $resource('api/cardGenerated/:branchCode:cardType', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
});
I always got 'Failed to load resource: the server responded with a status of 404 (Not Found)'.
Here you are missing / .
You have two path variable here.so default url is
localhost:8080/foo/bar/api/cardGenerated/FIRST_PATH_VARIABLE/SECOND_PATH_VARIABLE
branchCode (First path variabel)
cardType (Second path variable)
#RequestMapping(value = "/cardGenerated/{branchCode}/{cardType}"
And in frontend side too the same mistake while registering factory definition.
api/cardGenerated/:branchCode/:cardType'
All method is like
#RestController
#RequestMapping("/api")
public class CardGeneratedResource {
#RequestMapping(value = "/cardGenerated/{branchCode}/{cardType}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<CardGenerated> get(#PathVariable("branchCode") String branchCode,
#PathVariable("cardType") String cardType,
HttpServletResponse response) {
log.debug("REST request to get CardGenerated : " + branchCode + " and " + cardType);
CardGenerated cardGenerated = cardGeneratedRepository.
findTopByBranchCodeAndCardTypeOrderByCardNumberDesc(branchCode, cardType);
if (cardGenerated == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(cardGenerated, HttpStatus.OK);
}
}
and angular factory is like
'use strict';
angular.module('itmApp')
.factory('CardGenerated', function ($resource) {
return $resource('api/cardGenerated/:branchCode/:cardType', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
});
NOTE: First try with any rest client or postman and make sure backend api is working properly also angular side check parameters are being passed correctly.

Categories

Resources