Spring boot jpa can't insert row with string containing accents - javascript

I can"t understand the problem because i found nowhere the same problem.
i tried to insert product with type "pièces détachées". On the browser path /Produits the product doesn't show up but when i remove the accents from the string it's inserting in the mysql db. I tried to insert accents in the db the query is ok. But with my code it's impossible to do the same. here's a sample of my code for Produit :
//ajouter un produit
#PostMapping(value = "/Produits")
public ResponseEntity<Void> ajouterProduit(#RequestBody ProduitDTO produit) {
Produit produitCK = new Produit();
produitCK.setIdPM(new ProduitMagasin(produit.getId(), produit.getIdMagasin()));
produitCK.setDateAjout(produit.getDateAjout());
produitCK.setEtatProduit(produit.getEtatProduit());
produitCK.setIdReference(produit.getIdReference());
produitCK.setNumeroSerie(produit.getNumeroSerie());
produitCK.setPrixVente(produit.getPrixVente());
produitCK.setTVA(produit.getTVA());
produitCK.setType(produit.getType());
Produit produitAdded = produitDao.save(produitCK);
if (produitAdded == null)
return ResponseEntity.noContent().build();
else
return new ResponseEntity<>(HttpStatus.CREATED);
}
ProduitDTO :
package com.stationphone.db.model;
import java.sql.Timestamp;
/**
*
* #author Administrateur
*/
public class ProduitDTO {
private int id;
public enum Type {
PIECES {
public String getString() {
return "pièces detachées";
}
},
VENTE {
public String getString() {
return "vente en magasin";
}
};
public abstract String getString();
}
private String type;
private int id_reference;
private String numero_serie;
private Timestamp date_ajout;
private String marque;
private String modele;
private float prix_vente;
private double prixHT;
private float tva;
private String etat_produit;
private int id_magasin;
public int getId(){
return this.id;
}
public void setId(int id){
this.id=id;
}
public int getIdOnline(){
return this.id;
}
public void setIdOnline(int id){
this.id=id;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type=type;
}
public int getIdReference(){
return this.id_reference;
}
public void setIdReference(int id_reference){
this.id_reference=id_reference;
}
public String getNumeroSerie(){
return this.numero_serie;
}
public void setNumeroSerie(String numero_serie){
this.numero_serie=numero_serie;
}
public Timestamp getDateAjout(){
return this.date_ajout;
}
public void setDateAjout(Timestamp date_ajout){
this.date_ajout=date_ajout;
}
public String getMarque(){
return this.marque;
}
public void setMarque(String marque){
this.marque=marque;
}
public String getModele(){
return this.modele;
}
public void setModele(String modele){
this.modele=modele;
}
public float getPrixVente(){
return this.prix_vente;
}
public void setPrixVente(float prix){
this.prix_vente=prix;
}
public double getPrixHT(){
return this.prixHT;
}
public void setPrixHT(double prix){
this.prixHT=prix;
}
public float getTVA(){
return this.tva;
}
public void setTVA(float tva){
this.tva=tva;
}
public String getEtatProduit(){
return this.etat_produit;
}
public void setEtatProduit(String etat){
this.etat_produit=etat;
}
public int getIdMagasin(){
return this.id_magasin;
}
public void setIdMagasin(int id_magasin){
this.id_magasin=id_magasin;
}
}
class Produit :
package com.stationphone.db.model;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
/**
*
* #author Administrateur
*/
#Entity
public class Produit implements Serializable {
#EmbeddedId
private ProduitMagasin idPM;
#OneToOne
#JoinColumn(name = "id_magasin", insertable=false, updatable=false)
Magasin magasin;
public enum Type {
PIECES {
public String getString() {
return "pièces detachées";
}
},
VENTE {
public String getString() {
return "vente en magasin";
}
};
public abstract String getString();
}
private String type;
private int id_reference;
private String numero_serie;
private Timestamp date_ajout;
private float prix_vente;
private float tva;
private String etat_produit;
public ProduitMagasin getIdPM(){
return this.idPM;
}
public void setIdPM(ProduitMagasin id){
this.idPM=id;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type=type;
}
public int getIdReference(){
return this.id_reference;
}
public void setIdReference(int id_reference){
this.id_reference=id_reference;
}
public String getNumeroSerie(){
return this.numero_serie;
}
public void setNumeroSerie(String numero_serie){
this.numero_serie=numero_serie;
}
public Timestamp getDateAjout(){
return this.date_ajout;
}
public void setDateAjout(Timestamp date_ajout){
this.date_ajout=date_ajout;
}
public float getPrixVente(){
return this.prix_vente;
}
public void setPrixVente(float prix){
this.prix_vente=prix;
}
public float getTVA(){
return this.tva;
}
public void setTVA(float tva){
this.tva=tva;
}
public String getEtatProduit(){
return this.etat_produit;
}
public void setEtatProduit(String etat){
this.etat_produit=etat;
}
}
I hope i'll find an answer here. Thanks.
EDIT : the post method :
public static HttpResponse post(Object object, String type){
HttpResponse response=null;
try{
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost postRequest = new HttpPost(getUrl(type));
System.out.println(getUrl(type));
ObjectMapper mapper= new ObjectMapper();
String jsonInString = mapper.writeValueAsString(object);
System.out.println(jsonInString);
StringEntity input = new StringEntity(jsonInString);
input.setContentType("application/json");
postRequest.setEntity(input);
response = client.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println(response.getStatusLine().getStatusCode()+" ");
client.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
return response;
}
EDIT 2 : the error on tomcat local :
018-07-24 18:55:32.196 WARN 10860 --- [nio-8084-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP
message:
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Invalid UTF-8 middle byte 0x63
at [Source: (PushbackInputStream); line: 1, column: 21]; nested
exception is com.fasterxml.jackson.databind.JsonMappingException:
Invalid UTF-8 middle byte 0x63
at [Source: (PushbackInputStream); line: 1, column: 21]
at [Source: (PushbackInputStream); line: 1, column: 16] (through
reference
chain: com.stationphone.db.model.ProduitDTO["type"])

Thanks tp billy frost what to do 2 things :
HttpPost postRequest = new HttpPost(getUrl(type));
postRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
StringEntity input = new StringEntity(jsonInString, "UTF-8");

Related

How can I get a data from Spring-Security principal?

Now I face with some problems about principal data. Maybe it sounds like a fool. But I'm new to Spring..
I wanted to get some specific data from principal data, but it occured an error, So I cant.
this is my customUserDetails that implement UserDetails.
private String id;
private String pw;
private String name;
private String auth;
private String level;
private String label;
private int enabled;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority(auth));
return authList;
}
#Override
public String getPassword() {
return pw;
}
#Override
public String getUsername() {
return id;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return enabled==1?true:false;
}
public String getName() {
return name;
}
public String getLabel() { return label;} // 4월 19일 동현 추가
public void setName(String name) {
this.name = name;
}
public String getAuth() {
return auth;
}
And this is principal data I got from console.log
CustomUserDetails(id=admin, pw=$2a$10$Z9C0gTGV0weknBvNi4YFY.l41vjrYo4UgO3MlPwgmIn4uDeYlepFq, name=Admin, auth=ROLE_ADMIN, level=null, label=N, enabled=1)
I want to extract label value from Principal, so I tried to do this code, but I can't.
console.log('${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.label}');
How can I get 'label' data from principal?
Thank you for your kind support :)
In your Controller or any other bean, autowire user details like
public String doSomething(#AuthenticationPrincipal CustomUserDetails userDetails) {
String label = userDetails.getLabel();
}

Call php script inside java activity after click

I am parsing a JSON title, URL etc. from a PHP script. I want to give a reward with PHP script after the user click my link. Reward code -
String awr = Config.Base_Url+"videos/award.php";
Now everything is working, there is just no reward, no call to my PHP script...
How do i need modify my script to get correct reward? My java activity -
package com.uabclousy.pjanidemo;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.json.JSONArray;
import java.util.ArrayList;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.uabclousy.pjanidemo.app.App;
import com.uabclousy.pjanidemo.constants.Constants;
import org.json.JSONException;
import org.json.JSONObject;
import android.net.Uri;
import android.content.Intent;
public class ItemsActivity extends BaseActivity {
private PrefManager prf;
List<DataAdapter> ListOfdataAdapter;
RecyclerView recyclerView;
String HTTP_JSON_URL = "https://pjani.com/ImageJsonData.php";
String Image_Name_JSON = "image_title";
String Image_Decription_JSON = "app_description";
String Image_URL_JSON = "image_url";
String App_URL_JSON = "app_url";
String App_Message_JSON = "app_message";
String App_Points = "app_points";
String App_Id = "videoId";
String App_sec = "id";
public static final String EXTRA_VIDEO_ID = "id";
public static final String EXTRA_ID = "id";
JsonArrayRequest RequestOfJSonArray ;
RequestQueue requestQueue ;
View view ;
int RecyclerViewItemPosition ;
RecyclerView.LayoutManager layoutManagerOfrecyclerView;
RecyclerView.Adapter recyclerViewadapter;
ArrayList<String> ImageTitleNameArrayListForClick;
ArrayList<String> AppmessageArrayListForClick;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_items);
prf = new PrefManager(this);
getSupportActionBar().setIcon(R.drawable.ic_back_icon);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ImageTitleNameArrayListForClick = new ArrayList<>();
AppmessageArrayListForClick = new ArrayList<>();
ListOfdataAdapter = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerview1);
recyclerView.setHasFixedSize(true);
layoutManagerOfrecyclerView = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManagerOfrecyclerView);
JSON_HTTP_CALL();
validate();
// Implementing Click Listener on RecyclerView.
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
GestureDetector gestureDetector = new GestureDetector(ItemsActivity.this, new GestureDetector.SimpleOnGestureListener() {
#Override public boolean onSingleTapUp(MotionEvent motionEvent) {
return true;
}
});
#Override
public boolean onInterceptTouchEvent(RecyclerView Recyclerview, MotionEvent motionEvent) {
view = Recyclerview.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
if(view != null && gestureDetector.onTouchEvent(motionEvent)) {
//Getting RecyclerView Clicked Item value.
RecyclerViewItemPosition = Recyclerview.getChildAdapterPosition(view);
// Showing RecyclerView Clicked Item value using Toast.
Toast.makeText(ItemsActivity.this, AppmessageArrayListForClick.get(RecyclerViewItemPosition), Toast.LENGTH_LONG).show();
String url = ImageTitleNameArrayListForClick.get(RecyclerViewItemPosition);
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra("points", App_Points);
intent.putExtra("vid", App_Id);
intent.putExtra("id", App_sec);
intent.putExtra("yourreq4", "fuck13");
setResult(RESULT_OK, intent);
finish();
startActivity(intent);
}
return false;
}
#Override
public void onTouchEvent(RecyclerView Recyclerview, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
void award_items(final String points, final String tostore, final String type){
String awr = Config.Base_Url+"videos/award.php";
final String v1 ="1";
final String v0 ="0";
final String v2 ="2";
StringRequest stringRequest = new StringRequest(Request.Method.POST, awr,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Enable this only on testing - yash
//Toast.makeText(VideosActivity.this, response, Toast.LENGTH_LONG).show();
if(response.intern() == v1.intern()) {
Toast.makeText(ItemsActivity.this, points+" "+getString(R.string.points_received), Toast.LENGTH_SHORT).show();
prf.setBoolean(tostore, true);
Intent intent = getIntent();
finish();
startActivity(intent);
}
if(response.intern() == v0.intern()) {
Toast.makeText(ItemsActivity.this, getString(R.string.already_watched), Toast.LENGTH_SHORT).show();
prf.setBoolean(tostore, true);
Intent intent = getIntent();
finish();
startActivity(intent);
}
if(response.intern() == v2.intern()){
Toast.makeText(ItemsActivity.this,getString(R.string.server_problem),Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ItemsActivity.this,getString(R.string.server_problem),Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("username", App.getInstance().getUsername());
params.put("points",App_Points);
params.put("type",type);
params.put("videoid",Image_Name_JSON);
params.put("date","hehe");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_about, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
break;
case R.id.share:
shareURL();
return true;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
// sharing
void shareURL() {
try
{ Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
String sAux = getString(R.string.share_text)+"\n";
sAux = sAux + "https://play.google.com/store/apps/details?id="+getApplicationContext().getPackageName()+"\n";
i.putExtra(Intent.EXTRA_TEXT, sAux);
startActivity(Intent.createChooser(i, getString(R.string.choose_one)));
}
catch(Exception e)
{ //e.toString();
}
}
public void JSON_HTTP_CALL(){
RequestOfJSonArray = new JsonArrayRequest(HTTP_JSON_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
ParseJSonResponse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(ItemsActivity.this);
requestQueue.add(RequestOfJSonArray);
}
public void ParseJSonResponse(JSONArray array){
for(int i = 0; i<array.length(); i++) {
DataAdapter GetDataAdapter2 = new DataAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataAdapter2.setImageTitle(json.getString(Image_Name_JSON));
GetDataAdapter2.setImageDescription(json.getString(Image_Decription_JSON));
// Opening link in array to display on RecyclerView click event.
ImageTitleNameArrayListForClick.add(json.getString(App_URL_JSON));
// Adding message in array to display on RecyclerView click event.
AppmessageArrayListForClick.add(json.getString(App_Message_JSON));
GetDataAdapter2.setImageUrl(json.getString(Image_URL_JSON));
GetDataAdapter2.setAppPoints(json.getString(App_Points));
} catch (JSONException e) {
e.printStackTrace();
}
ListOfdataAdapter.add(GetDataAdapter2);
}
recyclerViewadapter = new RecyclerViewAdapter(ListOfdataAdapter, this);
recyclerView.setAdapter(recyclerViewadapter);
}
void validate(){
if (Config.Base_Url.intern() == Constants.API_License && !BuildConfig.DEBUG && Constants.release) {
App.getInstance().logout();
Intent i = new Intent(getApplicationContext(), AppActivity.class);
startActivity(i);
finish();
ActivityCompat.finishAffinity(ItemsActivity.this);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if(resultCode == RESULT_OK) {
award_items(data.getStringExtra("points"),data.getStringExtra("id"),getString(R.string.webpanel_credit));
// Toast.makeText(getApplicationContext(), data.getStringExtra("id"), Toast.LENGTH_SHORT).show();
}
}
}
}
Thank you very much for helping!

Cnverting JSON to Java Object using GSON

Can you please let me know what went wrong in the below sample.
Employee.java
public class Employee {
private String name;
public String getName() {
return name;
}
public String getAge() {
return age;
}
private String age;
}
JsontoJava.java
import com.google.gson.Gson;
public class JsontoJava {
public static void main(String ar[]){
Gson gson = new Gson();
String json = "{\"Employee\":[{\"name\":\"Test\", \"age\":\"12\"}]}";
Employee staff = gson.fromJson(json, Employee.class);
System.out.println("Name : "+staff.getName());
}
}
Unfortunately getting the wrong output:
Name :null
Your json is not right. Change to this.
{"name":"Test","age":"12"}

Nashorn runtime exception while printing JSObject implementations

I have a bean that implements JSObject ( & Map ) interface as shown below. I have removed some overridden methods to make it easy to read.
package test.nashorn;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import jdk.nashorn.api.scripting.JSObject;
public class JSBean implements JSObject, Map<String,Object>{
/**
* The current values for this object.
*/
private HashMap<String, Object> values = new HashMap<>();
#Override
public String toString() {
System.out.println("ToString");
Set<Entry<String,Object>> entries = values.entrySet();
StringBuilder sb = new StringBuilder();
for(Entry<String,Object> entry:entries){
sb.append(entry.getKey()+ " "+(String)entry.getValue());
}
System.out.println("Completed ToString");
return sb.toString();
}
#Override
public boolean hasMember(String name) {
return has(name);
}
// get the value of that named property
#Override
public Object getMember(String name) {
return get(name);
}
// get the value of that named property
#Override
public void setMember(String name,Object value) {
put(name,value);
}
public Object get(String name) {
System.out.println("JAVA Get is called."+name);
System.out.println("Called for this"+name+" and returned"
+":"+values.get(name));
return values.get(name);
}
#Override
public Object put(String name, Object value) {
System.out.println("JAVA Put is called. Input name: " + name + "\n Input values: " + value);
return values.put(name, value);
}
public boolean has(String name) {
System.out.println("JAVA Has is called. Input name: " + name);
return values.containsKey(name);
}
public JSBean() {
// TODO Auto-generated constructor stub
}
#Override
public Object call(Object arg0, Object... arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public Object eval(String arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public String getClassName() {
// TODO Auto-generated method stub
return null;
}
#Override
public Object getSlot(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean hasSlot(int arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isArray() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isFunction() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isInstance(Object arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isInstanceOf(Object arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isStrictFunction() {
// TODO Auto-generated method stub
return false;
}
}
When i run the test shown below
#Test
public void testDefaultValMethod(){
JSBean bean = new JSBean();
bean.setMember("hello", " Sport ");
//Add stuff to engine.
engine.put("jsBean", bean);
String source = "(function(){\n"
+ "print(jsBean);"
+ "} )();";
Object obj=null;
try {
obj = engine.eval(source);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Returned : " + String.valueOf(obj));
}
I see the below error in the console. Ideally Nashorn should have directly called the toString() method of the bean to get the String implementation. Not sure what is going wrong here. I did try adding a call to 'toString()' explicitly in the getMember() method call but that did not fix the problem.
JAVA Put is called. Input name: hello
Input values: Sport
JAVA Get is called.toString
Called for thistoString and returned:null
JAVA Get is called.valueOf
Called for thisvalueOf and returned:null
javax.script.ScriptException: TypeError: cannot.get.default.string in <eval> at line number 2
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at test.nashorn.NashornTest.testDefaultValMethod(NashornTest.java:386)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: <eval>:2 TypeError: cannot.get.default.string
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:514)
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:480)
at jdk.nashorn.internal.runtime.JSType.toStringImpl(JSType.java:1391)
at jdk.nashorn.internal.runtime.JSType.toString(JSType.java:589)
at jdk.nashorn.internal.objects.Global.printImpl(Global.java:2782)
at jdk.nashorn.internal.objects.Global.println(Global.java:1497)
at jdk.nashorn.internal.scripts.Script$Recompilation$1$11$\^eval\_.L:1(<eval>:2)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
... 29 more
Caused by: java.lang.UnsupportedOperationException: cannot.get.default.string
at jdk.nashorn.api.scripting.DefaultValueImpl.getDefaultValue(DefaultValueImpl.java:53)
at jdk.nashorn.api.scripting.AbstractJSObject.getDefaultValue(AbstractJSObject.java:289)
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:512)
... 40 more
Returned : null
print or "toString" conversions from scripts call "toString" method on the script object. Any property access (including function valued property) on a JSObject is routed to getMember method. So, to make "valueOf" or "toString" you've to implement appropriate getMember in your JSObject subtype.
Example:
import jdk.nashorn.api.scripting.*;
import javax.script.*;
public class Main {
static class MyJSObject extends AbstractJSObject {
#Override
public Object getMember(String name) {
if (name.equals("toString")) {
// return a "function" object for "toString" property
return new AbstractJSObject() {
#Override
public boolean isFunction() {
return true;
}
#Override
public Object call(Object self, Object...args) {
return self.toString();
}
};
}
return null; // other properties here
}
#Override
public String toString() {
return "my js object";
}
}
public static void main(String[] a) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
e.put("myObj", new MyJSObject());
e.eval("print(myObj)");
}
}
Alternatively, you can also override
Object getDefaultValue(final Class<?> hint) throws UnsupportedOperationException
method in your AbstractJSObject subclass.
import jdk.nashorn.api.scripting.*;
import javax.script.*;
public class Main2 {
static class MyJSObject extends AbstractJSObject {
#Override
public Object getDefaultValue(Class<?> hint) {
if (hint == String.class) {
return toString();
}
throw new UnsupportedOperationException("no conversion for " + hint);
}
#Override
public String toString() {
return "my js object";
}
}
public static void main(String[] a) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
e.put("myObj", new MyJSObject());
e.eval("print(myObj)");
}
}

How to define array property using jsinterop?

I am trying to define a javascript type using JsInterop but could not figure out how to define an array propery inside a type.
#JsType
public interface Task
{
// this works
#JsProperty String getTitle();
#JsProperty void setTitle(String title);
}
#JsType
public interface ViewModelInterface
{
// the following works
#JsProperty String getValue();
#JsProperty void setValue(String val);
// this does not work
#JsProperty Task[] getTasks();
#JsProperty void setTasks(Task[] tasks);
}
Is there any special syntax I should use?
Update:
I have come up with a temporary solution to the problem. I tried to use JNSI together with JsInterop and because the type define is javascript type we can add any property in that type after it is initialized.
The code is here
public class ViewModel implements ViewModelInterface
{
private String value;
public ViewModel()
{
value = "";
initTasksArray();
}
public String getValue() { return value; }
public void setValue(String val) { this.value = val; }
private native void initTasksArray()
/*-{
this.tasks =
[
{ title: 'Get high enough to grab the flag' },
{ title: 'Find the Princess' }
];
}*-/;
}
This way, the tasks property can be accessed from javascript as if it is defined as a #JsProperty. This is only a temporary solution and I am sure there will be a more proper one when JsInterop formally come out.
It should work as described.
Here is an example:
#JsType
public interface Task {
#JsProperty
String getTitle();
#JsProperty
void setTitle(String title);
public static Task getTask(String title) {
return new Task() {
private String title;
#Override
public String getTitle() {
return title;
}
#Override
public void setTitle(String title) {
this.title = title;
}
};
}
}
and
#JsType
public interface ViewModel {
#JsProperty
Task[] getTasks();
#JsProperty
void setTasks(Task[] tasks);
public static ViewModel getModel() {
return new ViewModel() {
Task[] tasks;
#Override
public void setTasks(Task[] tasks) {
this.tasks = tasks;
}
#Override
public Task[] getTasks() {
return tasks;
}
};
}
}
and the Javascript:
var model = ViewModel.getModel();
model.tasks = [Task.getTask('title1'), Task.getTask('title2')];
alert(model.tasks);

Categories

Resources